General DMR Tweaks; 64-bit IV from 32-bit MI;

This commit is contained in:
lwvmobile
2023-02-20 12:43:14 -05:00
parent 67e28c4655
commit 9cdbd35e51
5 changed files with 192 additions and 150 deletions

2
.gitignore vendored
View File

@@ -5,4 +5,6 @@ build
*.sh
*.csv
examples
*.bin
*.ans

View File

@@ -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

View File

@@ -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);

View File

@@ -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:

View File

@@ -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
}
}
}