From 9cdbd35e51e4f0333e6c04e22d99b9651bb29d43 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Mon, 20 Feb 2023 12:43:14 -0500 Subject: [PATCH] General DMR Tweaks; 64-bit IV from 32-bit MI; --- .gitignore | 2 + src/dmr_bs.c | 58 +++++++------------ src/dmr_data.c | 19 +++---- src/dmr_le.c | 149 ++++++++++++++++++++++++++++--------------------- src/dmr_pi.c | 114 ++++++++++++++++++++++++------------- 5 files changed, 192 insertions(+), 150 deletions(-) diff --git a/.gitignore b/.gitignore index 57ad766..c8daee9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ build *.sh *.csv examples +*.bin +*.ans diff --git a/src/dmr_bs.c b/src/dmr_bs.c index af0bf29..68a5218 100644 --- a/src/dmr_bs.c +++ b/src/dmr_bs.c @@ -114,13 +114,8 @@ void dmrBS (dsd_opts * opts, dsd_state * state) //disabled for dmr_cach testing tact_okay = 0; if ( Hamming_7_4_decode (tact_bits) ) tact_okay = 1; - if (tact_okay != 1) - { - if (opts->aggressive_framesync == 1) - { - goto END; - } - } + if (tact_okay != 1) goto END; //when going to end for bad tact or emb, consider using getdibit or skipdibit to 'stash' dibits and get better return on next sync pattern? in data particularly + internalslot = state->currentslot = tact_bits[1]; @@ -338,7 +333,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state) else sprintf (polarity, "%s", "-"); fprintf (stderr,"Sync: %sDMR %s| Color Code=%02d | VC%d ", polarity, light, state->dmr_color_code, vc); - + if (internalslot == 0 && vc1 == 6) { //process embedded link control @@ -465,18 +460,16 @@ void dmrBS (dsd_opts * opts, dsd_state * state) fprintf (stderr, "| VOICE CACH/EMB ERR"); fprintf (stderr, "%s", KNRM); fprintf (stderr, "\n"); - //run LFSR if either slot had an active MI in it. - if (state->payload_algid >= 0x21) + //run refresh if either slot had an active MI in it. + if (state->payload_algid != 0) { - state->currentslot = 0; - LFSR(state); - fprintf (stderr, "\n"); + state->currentslot = 0; + dmr_alg_refresh (opts, state); } - if (state->payload_algidR >= 0x21) + if (state->payload_algidR != 0) { - state->currentslot = 1; - LFSR(state); - fprintf (stderr, "\n"); + state->currentslot = 1; + dmr_alg_refresh (opts, state); } //failsafe to reset all data header and blocks when bad tact or emb @@ -514,7 +507,7 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state) 11, 12, 2, 13, 14, 15, 3, 16, 4, 17, 18, 19, 5, 20, 21, 22, 6, 23 - }; + }; //add time to mirror printFrameSync time_t now; char * getTime(void) //get pretty hh:mm:ss timestamp @@ -559,13 +552,8 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state) //decode and correct tact and compare if ( Hamming_7_4_decode (tact_bits) ) tact_okay = 1; - if (tact_okay != 1) - { - if (opts->aggressive_framesync == 1) - { - goto END; - } - } + if (tact_okay != 1) goto END; + internalslot = state->currentslot = tact_bits[1]; @@ -623,11 +611,8 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state) if ( strcmp (sync, DMR_BS_VOICE_SYNC) != 0) { - if (opts->aggressive_framesync == 1) - { - sync_okay = 0; - goto END; - } + sync_okay = 0; + goto END; } //Continue Second AMBE Frame, 18 after Sync or EmbeddedSignalling @@ -742,18 +727,17 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state) fprintf (stderr, "%s", KRED); fprintf (stderr, "| VOICE CACH/SYNC ERR"); fprintf (stderr, "%s", KNRM); - //run LFSR if either slot had an active MI in it. - if (state->payload_algid >= 0x21) + fprintf (stderr, "\n"); + //run refresh if either slot had an active MI in it. + if (state->payload_algid != 0) { state->currentslot = 0; - LFSR(state); - fprintf (stderr, "\n"); + dmr_alg_refresh (opts, state); } - if (state->payload_algidR >= 0x21) + if (state->payload_algidR != 0) { state->currentslot = 1; - LFSR(state); - fprintf (stderr, "\n"); + dmr_alg_refresh (opts, state); } //failsafe to reset all data header and blocks when bad tact or emb diff --git a/src/dmr_data.c b/src/dmr_data.c index b8904cb..b6509b6 100644 --- a/src/dmr_data.c +++ b/src/dmr_data.c @@ -75,12 +75,10 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state) if ( Hamming_7_4_decode (tact_bits) ) cach_okay = 1; else { + cach_okay = -1; - if (opts->aggressive_framesync == 1) - { - SlotTypeOk = 0; - goto END; - } + SlotTypeOk = 0; + goto END; } state->currentslot = tact_bits[1]; @@ -257,17 +255,14 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state) } /* Check and correct the SlotType (apply Golay(20,8) FEC check) */ - + // golay (20,8) hamming-weight of 6 reliably corrects at most 2 bit-errors if( Golay_20_8_decode(SlotType) ) SlotTypeOk = 1; else { - SlotTypeOk = -1; - if (opts->aggressive_framesync == 1) - { - SlotTypeOk = 0; - goto END; - } + + SlotTypeOk = 0; + goto END; } state->color_code = (SlotType[0] << 3) + (SlotType[1] << 2) +(SlotType[2] << 1) + (SlotType[3] << 0); diff --git a/src/dmr_le.c b/src/dmr_le.c index 71b1872..5e954a1 100644 --- a/src/dmr_le.c +++ b/src/dmr_le.c @@ -76,6 +76,12 @@ void dmr_late_entry_mi (dsd_opts * opts, dsd_state * state) fprintf (stderr, " Slot 1 PI/LFSR and Late Entry MI Mismatch - %08X : %08X \n", state->payload_mi, mi_final); state->payload_mi = mi_final; fprintf (stderr, "%s", KNRM); + } + //run afterwards, or le verification won't match up properly + if (state->payload_algid != 0x21) + { + LFSR64 (state); + fprintf (stderr, "\n"); } } if (slot == 1 && state->payload_algidR != 0) @@ -86,6 +92,12 @@ void dmr_late_entry_mi (dsd_opts * opts, dsd_state * state) fprintf (stderr, " Slot 2 PI/LFSR and Late Entry MI Mismatch - %08X : %08X \n", state->payload_miR, mi_final); state->payload_miR = mi_final; fprintf (stderr, "%s", KNRM); + } + //run afterwards, or le verification won't match up properly + if (state->payload_algidR != 0x21) + { + LFSR64 (state); + fprintf (stderr, "\n"); } } @@ -104,11 +116,13 @@ void dmr_alg_refresh (dsd_opts * opts, dsd_state * state) state->DMRvcL = 0; } - if (state->payload_algid >= 0x21) + if (state->payload_algid == 0x21) { LFSR (state); fprintf (stderr, "\n"); } + //LFSR64 carried out after LE verification in order to keep it from constantly resetting the MI to the previous value + } if (state->currentslot == 1) { @@ -119,11 +133,13 @@ void dmr_alg_refresh (dsd_opts * opts, dsd_state * state) state->DMRvcR = 0; } - if (state->payload_algidR >= 0x21) + if (state->payload_algidR == 0x21) { LFSR (state); fprintf (stderr, "\n"); } + //LFSR64 carried out after LE verification in order to keep it from constantly resetting the MI to the previous value + } } @@ -134,12 +150,11 @@ void dmr_alg_reset (dsd_opts * opts, dsd_state * state) state->dropR = 256; state->DMRvcL = 0; state->DMRvcR = 0; - state->payload_miP = 0; + state->payload_miP = 0; + state->payload_miN = 0; } //handle Single Burst (Voice Burst F) or Reverse Channel Signalling -//(Embedded or Dedicated Outbound, not Stand Alone (MS sourced) or Direct Mode) -//MS Sourced or Direct Mode probably would be handled poorly by the demodulator void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power) { int i; @@ -164,11 +179,11 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power) //power == 1 should be reverse channel -- still need to check the interleave inside of BPTC if (power == 1) irr_err = BPTC_16x2_Extract_Data(sbrc_interleaved, sbrc_return, 1); //bad emb burst, never set a valid power indicator value (probably 9) - if (power > 1) goto SBRC_END; + if (power > 1) goto SBRC_END; //RC Channel CRC 7 Mask = 0x7A; CRC bits are used as privacy indicators on //Single Voice Burst F (see below), other moto values seem to exist there as well - //unknown what the other values are (see Cap+ 0x313) + //unknown what the other values are (see Cap+ 0x313 and 0x643) if (power == 1) //RC { crc_extracted = 0; @@ -206,70 +221,78 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power) } } + //Disabling the lower portion until this can be completely ironed out + //sbrc_hex value of 0x313 seems to be some Cap+ Thing, //also observed 0x643 on another cap+ system (site id, status? something?) - //I've observed it in the Private Cap+ TXI calls as well - //there also seems to be a correlation between the SVC bits for TXI (reserved=3) and these extra cap+ values - uint8_t sbrc_opcode = sbrc_hex; - uint8_t alg = sbrc_hex & 0x7; - uint16_t key = (sbrc_hex >> 3) & 0xFF; + // uint8_t sbrc_opcode = sbrc_hex; + // uint8_t alg = sbrc_hex & 0x7; + // uint8_t key = (sbrc_hex >> 3) & 0xFF; - if (opts->payload == 1) - { - if (irr_err != 0) fprintf (stderr, "%s (FEC ERR) %d %s", KRED, irr_err, KNRM); - if (irr_err == 0) - { - if (sbrc_hex == 0) ; //NULL - else if (sbrc_hex == 0x313) - { - //Cap+ Thing? Observed On Cap+ Systems - // fprintf (stderr, " Cap+ Thing?"); - } - else - { + //this pattern seems to fit the multiple cap+ systems I've observed + //test on site '7' to make sure (works on 1 and 4) + // uint8_t cap_site = (sbrc_hex >> 4) & 0x7; - if (slot == 0) - { - //key and alg only present SOME times, not all, - //also, intermixed with other signalling - //needs more study first! - if (state->dmr_so & 0x40 && key != 0 && state->payload_keyid == 0) - { - if (opts->payload == 1) - { - fprintf (stderr, "%s ", KYEL); - fprintf (stderr, "\n Slot 1"); - fprintf (stderr, " DMR LE SB ALG ID: %X KEY ID: %0X", alg + 0x20, key); - fprintf (stderr, "%s ", KNRM); - } + // if (opts->payload == 1) + // { + // if (irr_err != 0) fprintf (stderr, "%s (FEC ERR) %d %s", KRED, irr_err, KNRM); + // if (irr_err == 0) + // { + // if (sbrc_hex == 0) ; //NULL + // else if (sbrc_hex == 0x313) //sbrc_hex == 0x313 and 0x643 (cap+ things) + // { + // //Cap+ Site ID seems to fit here on samples I've seen with the alternate SB signalling + // fprintf (stderr, "%s ", KYEL); + // fprintf (stderr, "\n "); + // fprintf (stderr, " Capacity Plus Site %d", cap_site); + // fprintf (stderr, "%s ", KNRM); + // } + // else + // { + + // if (slot == 0) + // { + // //key and alg only present SOME times, not all, + // //also, intermixed with other signalling + // //needs more study first! + // if (state->dmr_so & 0x40 && key != 0 && state->payload_keyid == 0) + // { + // if (opts->payload == 1) + // { + // fprintf (stderr, "%s ", KYEL); + // fprintf (stderr, "\n Slot 1"); + // fprintf (stderr, " DMR LE SB ALG ID: %X KEY ID: %0X", alg + 0x20, key); + // fprintf (stderr, "%s ", KNRM); + // } - //needs more study before assignment - //state->payload_keyid = key; - //state->payload_algid = alg + 0x20; //assuming DMRA approved alg values (moto patent) - } - } - if (slot == 1) - { - if (state->dmr_soR & 0x40 && key != 0 && state->payload_keyidR == 0) - { - if (opts->payload == 1) - { - fprintf (stderr, "%s ", KYEL); - fprintf (stderr, "\n Slot 2"); - fprintf (stderr, " DMR LE SB ALG ID: %X KEY ID: %0X", alg + 0x20, key); - fprintf (stderr, "%s ", KNRM); - } + // //needs more study before assignment + // // state->payload_keyid = key; + // // state->payload_algid = alg + 0x20; //assuming DMRA approved alg values (moto patent) + // } + // } + + // if (slot == 1) + // { + // if (state->dmr_soR & 0x40 && key != 0 && state->payload_keyidR == 0) + // { + // if (opts->payload == 1) + // { + // fprintf (stderr, "%s ", KYEL); + // fprintf (stderr, "\n Slot 2"); + // fprintf (stderr, " DMR LE SB ALG ID: %X KEY ID: %0X", alg + 0x20, key); + // fprintf (stderr, "%s ", KNRM); + // } - //needs more study before assignment - //state->payload_keyidR = key; - //state->payload_algidR = alg + 0x20; //assuming DMRA approved alg values (moto patent) - } - } + // //needs more study before assignment + // // state->payload_keyidR = key; + // // state->payload_algidR = alg + 0x20; //assuming DMRA approved alg values (moto patent) + // } + // } - } + // } - } - } + // } + // } SBRC_END: diff --git a/src/dmr_pi.c b/src/dmr_pi.c index f3abb4c..ecece68 100644 --- a/src/dmr_pi.c +++ b/src/dmr_pi.c @@ -15,15 +15,11 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC if((IrrecoverableErrors == 0)) { + if (state->currentslot == 0) { - - if (0 == 0) - { - state->payload_algid = PI_BYTE[0]; - state->payload_keyid = PI_BYTE[2]; - } - + state->payload_algid = PI_BYTE[0]; + state->payload_keyid = PI_BYTE[2]; state->payload_mi = ( ((PI_BYTE[3]) << 24) + ((PI_BYTE[4]) << 16) + ((PI_BYTE[5]) << 8) + (PI_BYTE[6]) ); if (state->payload_algid < 0x26) { @@ -31,27 +27,26 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC fprintf (stderr, "\n Slot 1"); fprintf (stderr, " DMR PI H- ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08X", state->payload_algid, state->payload_keyid, state->payload_mi); fprintf (stderr, "%s ", KNRM); + if (state->payload_algid != 0x21) + { + fprintf (stderr, "\n"); + LFSR64 (state); + } } if (state->payload_algid >= 0x26) { - if (0 == 0) - { - state->payload_algid = 0; - state->payload_keyid = 0; - state->payload_mi = 0; - } + state->payload_algid = 0; + state->payload_keyid = 0; + state->payload_mi = 0; } } if (state->currentslot == 1) { - if (0 == 0) - { - state->payload_algidR = PI_BYTE[0]; - state->payload_keyidR = PI_BYTE[2]; - } + state->payload_algidR = PI_BYTE[0]; + state->payload_keyidR = PI_BYTE[2]; state->payload_miR = ( ((PI_BYTE[3]) << 24) + ((PI_BYTE[4]) << 16) + ((PI_BYTE[5]) << 8) + (PI_BYTE[6]) ); if (state->payload_algidR < 0x26) { @@ -59,20 +54,23 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC fprintf (stderr, "\n Slot 2"); fprintf (stderr, " DMR PI H- ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08X", state->payload_algidR, state->payload_keyidR, state->payload_miR); fprintf (stderr, "%s ", KNRM); + if (state->payload_algidR != 0x21) + { + fprintf (stderr, "\n"); + LFSR64 (state); + } } if (state->payload_algidR >= 0x26) { - if (0== 0) - { - state->payload_algidR = 0; - state->payload_keyidR = 0; - state->payload_miR = 0; - } + state->payload_algidR = 0; + state->payload_keyidR = 0; + state->payload_miR = 0; } + } + } - } void LFSR(dsd_state * state) @@ -95,27 +93,67 @@ void LFSR(dsd_state * state) if (state->currentslot == 0) { - if (1 == 1) - { - fprintf (stderr, "%s", KYEL); - fprintf (stderr, " Slot 1"); - fprintf (stderr, " DMR PI C- ALG ID: 0x%02X KEY ID: 0x%02X", state->payload_algid, state->payload_keyid); - fprintf(stderr, " Next MI: 0x%08X", lfsr); - fprintf (stderr, "%s", KNRM); - } + fprintf (stderr, "%s", KYEL); + fprintf (stderr, " Slot 1"); + fprintf (stderr, " DMR PI C- ALG ID: 0x%02X KEY ID: 0x%02X", state->payload_algid, state->payload_keyid); + fprintf(stderr, " MI: 0x%08X", lfsr); + fprintf (stderr, "%s", KNRM); state->payload_mi = lfsr; } if (state->currentslot == 1) { - if (1 == 1) + + fprintf (stderr, "%s", KYEL); + fprintf (stderr, " Slot 2"); + fprintf (stderr, " DMR PI C- ALG ID: 0x%02X KEY ID: 0x%02X", state->payload_algidR, state->payload_keyidR); + fprintf(stderr, " MI: 0x%08X", lfsr); + fprintf (stderr, "%s", KNRM); + state->payload_miR = lfsr; + } +} + +void LFSR64(dsd_state * state) +{ + { + uint64_t lfsr = 0; + + if (state->currentslot == 0) + { + lfsr = (uint64_t) state->payload_mi; + } + else lfsr = (uint64_t) state->payload_miR; + + uint8_t cnt = 0; + + for(cnt=0;cnt<32;cnt++) { + uint64_t bit = ( (lfsr >> 31) ^ (lfsr >> 21) ^ (lfsr >> 1) ^ (lfsr >> 0) ) & 0x1; + lfsr = (lfsr << 1) | bit; + } + + // if (state->currentslot == 0) state->payload_miP = lfsr; + // else state->payload_miN = lfsr; + + if (state->currentslot == 0) + { + fprintf (stderr, "%s", KYEL); + fprintf (stderr, " Slot 1"); + fprintf (stderr, " DMR PI C- ALG ID: 0x%02X KEY ID: 0x%02X", state->payload_algid, state->payload_keyid); + fprintf (stderr, " MI: 0x%016lX", lfsr); + fprintf (stderr, "%s", KNRM); + state->payload_mi = lfsr & 0xFFFFFFFF; //truncate for next repitition and le verification + } + + if (state->currentslot == 1) + { fprintf (stderr, "%s", KYEL); fprintf (stderr, " Slot 2"); fprintf (stderr, " DMR PI C- ALG ID: 0x%02X KEY ID: 0x%02X", state->payload_algidR, state->payload_keyidR); - fprintf(stderr, " Next MI: 0x%08X", lfsr); + fprintf (stderr, " MI: 0x%016lX", lfsr); fprintf (stderr, "%s", KNRM); - } - state->payload_miR = lfsr; - } + state->payload_miR = lfsr & 0xFFFFFFFF; //truncate for next repitition and le verification + } + + } } \ No newline at end of file