From a9742043b8ada9433a1922e7369c7d5a98473500 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Mon, 20 Feb 2023 12:43:16 -0500 Subject: [PATCH] General DMR Tweaks; 64-bit IV from 32-bit MI; --- .gitignore | 2 + src/dmr_bs.c | 45 +++++---------- src/dmr_data.c | 14 ++--- src/dmr_le.c | 149 ++++++++++++++++++++++++++++--------------------- src/dmr_pi.c | 114 ++++++++++++++++++++++++------------- 5 files changed, 182 insertions(+), 142 deletions(-) diff --git a/.gitignore b/.gitignore index 019a9fb..1d8d34e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ build *.sh *.csv examples +*.bin +*.ans diff --git a/src/dmr_bs.c b/src/dmr_bs.c index cc32799..ef0b77d 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; + internalslot = state->currentslot = tact_bits[1]; @@ -478,18 +473,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. + //run refresh if either slot had an active MI in it. if (state->payload_algid >= 0x21) { - state->currentslot = 0; - LFSR(state); - fprintf (stderr, "\n"); + state->currentslot = 0; + dmr_alg_refresh (opts, state); } if (state->payload_algidR >= 0x21) { - 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 @@ -572,13 +565,7 @@ 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]; @@ -636,11 +623,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 @@ -755,18 +739,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. + fprintf (stderr, "\n"); + //run refresh if either slot had an active MI in it. if (state->payload_algid >= 0x21) { state->currentslot = 0; - LFSR(state); - fprintf (stderr, "\n"); + dmr_alg_refresh (opts, state); } if (state->payload_algidR >= 0x21) { 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 b1ce078..3e169b3 100644 --- a/src/dmr_data.c +++ b/src/dmr_data.c @@ -76,11 +76,8 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state) else { cach_okay = -1; - if (opts->aggressive_framesync == 1) - { - SlotTypeOk = 0; - goto END; - } + SlotTypeOk = 0; + goto END; } state->currentslot = tact_bits[1]; @@ -262,11 +259,8 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state) 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