diff --git a/include/dsd.h b/include/dsd.h index 5812b62..97ec1a4 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -460,6 +460,10 @@ typedef struct unsigned long long int payload_miP; int p25vc; unsigned long long int K; + unsigned long long int K1; + unsigned long long int K2; + unsigned long long int K3; + unsigned long long int K4; int menuopen; unsigned int debug_audio_errors; @@ -848,6 +852,7 @@ void ProcessUnifiedData(dsd_opts * opts, dsd_state * state, uint8_t info[196], u //LFSR code courtesy of https://github.com/mattames/LFSR/ int LFSR(dsd_state * state); +void LFSRN (char * BufferIn, char * BufferOut, dsd_state * state); void Hamming_7_4_init(); void Hamming_7_4_encode(unsigned char *origBits, unsigned char *encodedBits); diff --git a/src/dmr_bs.c b/src/dmr_bs.c index 1e001b3..84f0d1e 100644 --- a/src/dmr_bs.c +++ b/src/dmr_bs.c @@ -374,10 +374,23 @@ void dmrBS (dsd_opts * opts, dsd_state * state) fprintf(stderr, " PrK %lld", state->K); fprintf (stderr, "%s", KNRM); } - if (state->H > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) + if (state->DMRvcL == 0 && state->K1 > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) { + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); + fprintf(stderr, " SPT %016llX", state->K1); + if (state->K2 != 0) + { + fprintf(stderr, " %016llX", state->K2); + } + if (state->K3 != 0) + { + fprintf(stderr, " %016llX", state->K3); + } + if (state->K4 != 0) + { + fprintf(stderr, " %016llX", state->K4); + } fprintf (stderr, "%s", KNRM); } fprintf (stderr, "\n"); @@ -391,10 +404,23 @@ void dmrBS (dsd_opts * opts, dsd_state * state) fprintf(stderr, " PrK %lld", state->K); fprintf (stderr, "%s", KNRM); } - if (state->H > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) + if (state->DMRvcL == 0 && state->K1 > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) { + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); + fprintf(stderr, " SPT %016llX", state->K1); + if (state->K2 != 0) + { + fprintf(stderr, " %016llX", state->K2); + } + if (state->K3 != 0) + { + fprintf(stderr, " %016llX", state->K3); + } + if (state->K4 != 0) + { + fprintf(stderr, " %016llX", state->K4); + } fprintf (stderr, "%s", KNRM); } fprintf (stderr, "\n"); @@ -413,10 +439,23 @@ void dmrBS (dsd_opts * opts, dsd_state * state) fprintf(stderr, " PrK %lld", state->K); fprintf (stderr, "%s", KNRM); } - if (state->H > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) + if (state->DMRvcR == 0 && state->K1 > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) { + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); + fprintf(stderr, " SPT %016llX", state->K1); + if (state->K2 != 0) + { + fprintf(stderr, " %016llX", state->K2); + } + if (state->K3 != 0) + { + fprintf(stderr, " %016llX", state->K3); + } + if (state->K4 != 0) + { + fprintf(stderr, " %016llX", state->K4); + } fprintf (stderr, "%s", KNRM); } fprintf (stderr, "\n"); @@ -430,10 +469,23 @@ void dmrBS (dsd_opts * opts, dsd_state * state) fprintf(stderr, " PrK %lld", state->K); fprintf (stderr, "%s", KNRM); } - if (state->H > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) + if (state->DMRvcR == 0 && state->K1 > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) { + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); + fprintf(stderr, " SPT %016llX", state->K1); + if (state->K2 != 0) + { + fprintf(stderr, " %016llX", state->K2); + } + if (state->K3 != 0) + { + fprintf(stderr, " %016llX", state->K3); + } + if (state->K4 != 0) + { + fprintf(stderr, " %016llX", state->K4); + } fprintf (stderr, "%s", KNRM); } fprintf (stderr, "\n"); @@ -718,11 +770,24 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state) fprintf (stderr, "%s", KNRM); } - if ( (state->H > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) || - (state->K > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) ) + if ( (state->K1 > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) || + (state->K1 > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) ) { + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); + fprintf(stderr, " SPT %016llX", state->K1); + if (state->K2 != 0) + { + fprintf(stderr, " %016llX", state->K2); + } + if (state->K3 != 0) + { + fprintf(stderr, " %016llX", state->K3); + } + if (state->K4 != 0) + { + fprintf(stderr, " %016llX", state->K4); + } fprintf (stderr, "%s", KNRM); } fprintf (stderr, "\n"); @@ -738,11 +803,24 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state) fprintf (stderr, "%s", KNRM); } - if ( (state->H > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) || - (state->K > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) ) + if ( (state->K1 > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) || + (state->K1 > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) ) { + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); + fprintf(stderr, " SPT %016llX", state->K1); + if (state->K2 != 0) + { + fprintf(stderr, " %016llX", state->K2); + } + if (state->K3 != 0) + { + fprintf(stderr, " %016llX", state->K3); + } + if (state->K4 != 0) + { + fprintf(stderr, " %016llX", state->K4); + } fprintf (stderr, "%s", KNRM); } fprintf (stderr, "\n"); diff --git a/src/dmr_ms.c b/src/dmr_ms.c index b2f67e8..57855ee 100644 --- a/src/dmr_ms.c +++ b/src/dmr_ms.c @@ -372,10 +372,23 @@ void dmrMS (dsd_opts * opts, dsd_state * state) fprintf(stderr, " PrK %lld", state->K); fprintf (stderr, "%s", KNRM); } - if (state->H > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) + if (state->DMRvcL == 0 && state->K1 > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) { + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); + fprintf(stderr, " SPT %016llX", state->K1); + if (state->K2 != 0) + { + fprintf(stderr, " %016llX", state->K2); + } + if (state->K3 != 0) + { + fprintf(stderr, " %016llX", state->K3); + } + if (state->K4 != 0) + { + fprintf(stderr, " %016llX", state->K4); + } fprintf (stderr, "%s", KNRM); } fprintf (stderr, "\n"); @@ -390,10 +403,23 @@ void dmrMS (dsd_opts * opts, dsd_state * state) fprintf(stderr, " PrK %lld", state->K); fprintf (stderr, "%s", KNRM); } - if (state->H > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) + if (state->DMRvcL == 0 && state->K1 > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) { + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); + fprintf(stderr, " SPT %016llX", state->K1); + if (state->K2 != 0) + { + fprintf(stderr, " %016llX", state->K2); + } + if (state->K3 != 0) + { + fprintf(stderr, " %016llX", state->K3); + } + if (state->K4 != 0) + { + fprintf(stderr, " %016llX", state->K4); + } fprintf (stderr, "%s", KNRM); } fprintf (stderr, "\n"); @@ -459,6 +485,7 @@ void dmrMS (dsd_opts * opts, dsd_state * state) state->dmr_stereo = 0; state->dmr_ms_mode = 0; state->dmr_ms_rc = 0; + state->DMRvcL = 0; } @@ -632,13 +659,26 @@ void dmrMSBootstrap (dsd_opts * opts, dsd_state * state) fprintf(stderr, " PrK %lld", state->K); fprintf (stderr, "%s", KNRM); } - if ( (state->H > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) || - (state->K > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fid == 0x68) ) + if ( (state->DMRvcL == 0 && state->K1 > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) || + (state->DMRvcR == 0 && state->K1 > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fid == 0x68) ) { + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); - fprintf (stderr, "%s", KNRM); + fprintf(stderr, " SPT %016llX", state->K1); + if (state->K2 != 0) + { + fprintf(stderr, " %016llX", state->K2); + } + if (state->K3 != 0) + { + fprintf(stderr, " %016llX", state->K3); + } + if (state->K4 != 0) + { + fprintf(stderr, " %016llX", state->K4); + } } + fprintf (stderr, "%s", KNRM); fprintf (stderr, "\n"); } else @@ -651,13 +691,26 @@ void dmrMSBootstrap (dsd_opts * opts, dsd_state * state) fprintf(stderr, " PrK %lld", state->K); fprintf (stderr, "%s", KNRM); } - if ( (state->H > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) || - (state->K > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fid == 0x68) ) + if ( (state->DMRvcL == 0 && state->K1 > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) || + (state->DMRvcR == 0 && state->K1 > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fid == 0x68) ) { + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); - fprintf (stderr, "%s", KNRM); + fprintf(stderr, " SPT %016llX", state->K1); + if (state->K2 != 0) + { + fprintf(stderr, " %016llX", state->K2); + } + if (state->K3 != 0) + { + fprintf(stderr, " %016llX", state->K3); + } + if (state->K4 != 0) + { + fprintf(stderr, " %016llX", state->K4); + } } + fprintf (stderr, "%s", KNRM); fprintf (stderr, "\n"); } diff --git a/src/dmr_process_voice.c b/src/dmr_process_voice.c index b3fc351..a4c5235 100644 --- a/src/dmr_process_voice.c +++ b/src/dmr_process_voice.c @@ -114,68 +114,148 @@ if (state->currentslot == 1 && state->K > 0 && state->dmr_soR & 0x40 && state->p } } -if (state->currentslot == 0 && state->H > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) +if (state->currentslot == 0 && state->K1 > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) { + int pos = 0; + + unsigned long long int k1 = state->K1; + unsigned long long int k2 = state->K2; + unsigned long long int k3 = state->K3; + unsigned long long int k4 = state->K4; + + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); + fprintf(stderr, " SPT %010llX", k1); + + int T_Key[256] = {0}; + int pN[882] = {0}; + + int len = 0; + + if (k2 == 0) + { + len = 39; + k1 = k1 << 24; + } + if (k2 != 0) + { + len = 127; + fprintf(stderr, " %016llX", k2); + } + if (k4 != 0) + { + len = 255; + fprintf(stderr, " %016llX", k3); + fprintf(stderr, " %016llX", k4); + } + fprintf (stderr, "%s", KNRM); - k = state->H; - unsigned long long int msb = 0; + for (i = 0; i < 64; i++) + { + T_Key[i] = ( ((k1 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+64] = ( ((k2 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+128] = ( ((k3 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+192] = ( ((k4 << i) & 0x8000000000000000) >> 63 ); + } - k = k << 8; - k = k | ((k >> 40) & 0xFF); + for (i = 0; i < 882; i++) + { + pN[i] = T_Key[pos]; + pos++; + if (pos > len) + { + pos = 0; + } + } - for(Frame = 0; Frame < 6; Frame++) + pos = 0; + for(Frame = 0; Frame < 6; Frame++) { for(i = 0; i < 3; i++) { - for(j = 0; j < 48; j++) + for(j = 0; j < 49; j++) { - x = ( ((k << j) & 0x800000000000) >> 47 ); - TSVoiceSupFrameL->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i][j] ^= x; - } - - k = k << 1; - msb = (k >> 32) & 0xFFFF; - k = (k << 8) & 0xFFFFFFFF0000; - k = k | msb; - + TSVoiceSupFrameL->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i][j] ^= pN[pos]; + pos++; + } } + } + } -if (state->currentslot == 1 && state->H > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) +if (state->currentslot == 1 && state->K1 > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) { + int pos = 0; + + unsigned long long int k1 = state->K1; + unsigned long long int k2 = state->K2; + unsigned long long int k3 = state->K3; + unsigned long long int k4 = state->K4; + + fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf(stderr, " T10 %010llX", state->H); + fprintf(stderr, " SPT %010llX", k1); + + int T_Key[256] = {0}; + int pN[882] = {0}; + + int len = 0; + + if (k2 == 0) + { + len = 39; + k1 = k1 << 24; + } + if (k2 != 0) + { + len = 127; + fprintf(stderr, " %016llX", k2); + } + if (k4 != 0) + { + len = 255; + fprintf(stderr, " %016llX", k3); + fprintf(stderr, " %016llX", k4); + } + fprintf (stderr, "%s", KNRM); - k = state->H; - unsigned long long int msb = 0; + for (i = 0; i < 64; i++) + { + T_Key[i] = ( ((k1 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+64] = ( ((k2 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+128] = ( ((k3 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+192] = ( ((k4 << i) & 0x8000000000000000) >> 63 ); + } - k = k << 8; - k = k | ((k >> 40) & 0xFF); + for (i = 0; i < 882; i++) + { + pN[i] = T_Key[pos]; + pos++; + if (pos > len) + { + pos = 0; + } + } - for(Frame = 0; Frame < 6; Frame++) + pos = 0; + for(Frame = 0; Frame < 6; Frame++) { for(i = 0; i < 3; i++) { - for(j = 0; j < 48; j++) + for(j = 0; j < 49; j++) { - x = ( ((k << j) & 0x800000000000) >> 47 ); - TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i][j] ^= x; - } - - k = k << 1; - msb = (k >> 32) & 0xFFFF; - k = (k << 8) & 0xFFFFFFFF0000; - k = k | msb; - + TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i][j] ^= pN[pos]; + pos++; + } } + } + } if (state->currentslot == 0) diff --git a/src/dmr_sync.c b/src/dmr_sync.c index cacb0ad..128401e 100644 --- a/src/dmr_sync.c +++ b/src/dmr_sync.c @@ -32,8 +32,6 @@ char * getTimeL(void) //get pretty hh:mm:ss timestamp return curr; } -//getDate has a bug that affects writing to file using fopen 32-bit Ubuntu OS, need to look into -//increasing array size causes date to not print in Linux builds, but fixes cygwin bug, so reverting to 99 until a better fix is worked out. char * getDateL(void) { char datename[120]; //increased to 200 to fix 32-bit Ubuntu/Cygwin when fopen file printing to lrrp.txt char * curr2; @@ -2199,10 +2197,8 @@ void ProcessDmrTerminaisonLC(dsd_opts * opts, dsd_state * state, uint8_t info[19 state->payload_algid = 0; state->payload_keyid = 0; state->payload_mi = 0; - // state->dmr_fid = TSVoiceSupFrame->FullLC.FeatureSetID; - // state->dmr_so = TSVoiceSupFrame->FullLC.ServiceOptions; - //state->dmr_fid = 0; - //state->dmr_so = 0; //leave disabled so will persist to aid in muting or unmuting when required + state->dmr_fid = 0; + state->dmr_so = 0; state->lastsrc = 0; state->lasttg = 0; @@ -2212,10 +2208,8 @@ void ProcessDmrTerminaisonLC(dsd_opts * opts, dsd_state * state, uint8_t info[19 state->payload_algidR = 0; state->payload_keyidR = 0; state->payload_miR = 0; - // state->dmr_fidR = TSVoiceSupFrame->FullLC.FeatureSetID; - // state->dmr_soR = TSVoiceSupFrame->FullLC.ServiceOptions; - //state->dmr_fidR = 0; - //state->dmr_soR = 0; + state->dmr_fidR = 0; + state->dmr_soR = 0; state->lastsrcR = 0; state->lasttgR = 0; @@ -2230,21 +2224,6 @@ void ProcessDmrTerminaisonLC(dsd_opts * opts, dsd_state * state, uint8_t info[19 fprintf(stderr, "FID=0x%02X SVC=0x%02X", TSVoiceSupFrame->FullLC.FeatureSetID, TSVoiceSupFrame->FullLC.ServiceOptions); fprintf (stderr, "%s ", KNRM); - if (TSVoiceSupFrame->FullLC.FullLinkControlOpcode == 0) //other opcodes may convey callsigns, names, etc. - { - if (state->currentslot == 0) - { - // state->dmr_fid = TSVoiceSupFrame->FullLC.FeatureSetID; - // state->dmr_so = TSVoiceSupFrame->FullLC.ServiceOptions; - //zero out src and tgt here as well, or will that cause issues with ncurses terminal and per call? - } - if (state->currentslot == 1) - { - // state->dmr_fidR = TSVoiceSupFrame->FullLC.FeatureSetID; - // state->dmr_soR = TSVoiceSupFrame->FullLC.ServiceOptions; - //zero out src and tgt here as well, or will that cause issues with ncurses terminal and per call? - } - } } else if(IrrecoverableErrors == 0) { @@ -2254,20 +2233,7 @@ void ProcessDmrTerminaisonLC(dsd_opts * opts, dsd_state * state, uint8_t info[19 fprintf(stderr, "FID=0x%02X SVC=0x%02X", TSVoiceSupFrame->FullLC.FeatureSetID, TSVoiceSupFrame->FullLC.ServiceOptions); fprintf(stderr, "RAS (FEC OK/CRC ERR)"); //tlc fprintf (stderr, "%s ", KNRM); - if (TSVoiceSupFrame->FullLC.FullLinkControlOpcode == 0) //other opcodes may convey callsigns, names, etc. - { - if (state->currentslot == 0) - { - // state->dmr_fid = TSVoiceSupFrame->FullLC.FeatureSetID; - // state->dmr_so = TSVoiceSupFrame->FullLC.ServiceOptions; - } - if (state->currentslot == 1) - { - // state->dmr_fidR = TSVoiceSupFrame->FullLC.FeatureSetID; - // state->dmr_soR = TSVoiceSupFrame->FullLC.ServiceOptions; - } - } } else {} //fprintf(stderr, "\n(FEC FAIL/CRC ERR)"); @@ -2660,13 +2626,10 @@ void ProcessVoiceBurstSync(dsd_opts * opts, dsd_state * state) { fprintf (stderr, "%s", KCYN); fprintf (stderr, "\nFull Voice Burst Payload "); - //for (i = 0; i < 8; i++) for (i = 0; i < 10; i++) { - fprintf (stderr, "[%02X]", LC_DataBytes[i]); //amateur DMR hams seem to use this area to send callsigns and names using 04,05,06,07 opcodes + fprintf (stderr, "[%02X]", LC_DataBytes[i]); } - // fprintf(stderr, "\n"); - // fprintf(stderr, "CRC extracted = 0x%04X - CRC computed = 0x%04X - ", CRCExtracted, CRCComputed); fprintf (stderr, "%s", KNRM); @@ -2677,7 +2640,7 @@ void ProcessVoiceBurstSync(dsd_opts * opts, dsd_state * state) //LFSR code courtesy of https://github.com/mattames/LFSR/ int LFSR(dsd_state * state) { - //int lfsr = 0; + int lfsr = 0; if (state->currentslot == 0) { @@ -2686,14 +2649,12 @@ int LFSR(dsd_state * state) else lfsr = state->payload_miR; uint8_t cnt = 0; - //fprintf(stderr, "\nInitial Value:- 0x%08x\n", lfsr); for(cnt=0;cnt<32;cnt++) { // Polynomial is C(x) = x^32 + x^4 + x^2 + 1 int bit = ((lfsr >> 31) ^ (lfsr >> 3) ^ (lfsr >> 1)) & 0x1; lfsr = (lfsr << 1) | (bit); - //fprintf(stderr, "\nshift #%i, 0x%08x\n", (cnt+1), lfsr); } if (state->currentslot == 0) { diff --git a/src/dsd_main.c b/src/dsd_main.c index a7a0349..4c69810 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -480,6 +480,10 @@ initState (dsd_state * state) state->K = 0; state->R = 0; state->H = 0; + state->K1 = 0; + state->K2 = 0; + state->K3 = 0; + state->K4 = 0; state->dmr_stereo = 0; state->dmrburstL = 17; //initialize at higher value than possible @@ -621,9 +625,6 @@ usage () printf (" (default=36)\n"); printf (" -M Min/Max buffer size for QPSK decision point tracking\n"); printf (" (default=15)\n"); - // printf (" -n Reset P25 Heuristics and initState variables on mixed signal decoding\n"); - // printf (" Helps when decoding mixed signal types (P25P1) at same time\n"); - // printf (" (WiP! May Cause Slow Memory Leak or System Hang - Experimental)\n"); printf (" -T Enable DMR TDMA Stereo Voice (Two Slot Dual Voices)\n"); printf (" This feature will open two streams for slot 1 voice and slot 2 voice\n"); printf (" May Cause Skipping or sync issues if bad signal/errors\n"); @@ -634,7 +635,10 @@ usage () printf ("\n"); printf (" -K Manually Enter DMRA Privacy Key (Decimal Value of Key Number)\n"); printf ("\n"); - printf (" -H Manually Enter 'Tera 10 Privacy Key (40-Bit/10-Char Hex Value)\n"); + printf (" -H Manually Enter **tera 10 Privacy Key (40-Bit/10-Char Hex Value)\n"); + printf (" (32/64-Char values can only be entered in the NCurses Terminal)\n"); + printf (" -R Manually Enter NXDN 4800 EHR Scrambler Key Value \n"); + printf (" \n"); printf ("\n"); exit (0); } @@ -953,6 +957,21 @@ main (int argc, char **argv) } break; + case 'R': + sscanf (optarg, "%lld", &state.R); + if (state.R > 0x7FFF) + { + state.R = 0x7FFF; + } + // opts.dmr_mute_encL = 0; + // opts.dmr_mute_encR = 0; + if (state.R == 0) + { + // opts.dmr_mute_encL = 1; + // opts.dmr_mute_encR = 1; + } + break; + case 'H': sscanf (optarg, "%llX", &state.H); if (state.H > 0xFFFFFFFFFF) @@ -966,6 +985,7 @@ main (int argc, char **argv) opts.dmr_mute_encL = 1; opts.dmr_mute_encR = 1; } + state.K1 = state.H; //shim break; case 'G': //Set rtl device gain @@ -1099,10 +1119,10 @@ main (int argc, char **argv) opts.serial_dev[1023] = '\0'; break; - case 'R': - sscanf (optarg, "%d", &opts.resume); - fprintf (stderr,"Enabling scan resume after %i TDULC frames\n", opts.resume); - break; + // case 'R': + // sscanf (optarg, "%d", &opts.resume); + // fprintf (stderr,"Enabling scan resume after %i TDULC frames\n", opts.resume); + // break; case 'f': if (optarg[0] == 'a') diff --git a/src/dsd_mbe.c b/src/dsd_mbe.c index 9f516b8..7e41258 100644 --- a/src/dsd_mbe.c +++ b/src/dsd_mbe.c @@ -202,6 +202,23 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a mbe_demodulateAmbe3600x2450Data (ambe_fr); state->errs2 += mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d); + if (state->nxdn_cipher_type == 0x01 && state->R > 0) //reuse R for scrambler key + { + + if (state->payload_miN == 0) + { + state->payload_miN = state->R; + } + + char ambe_temp[49]; + for (short int i = 0; i < 49; i++) + { + ambe_temp[i] = ambe_d[i]; + ambe_d[i] = 0; + } + LFSRN(ambe_temp, ambe_d, state); + + } mbe_processAmbe2450Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality); @@ -239,34 +256,60 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a } } - if (state->currentslot == 0 && state->H > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) + if (state->K1 > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) { - unsigned long long int msb = 0; - if (state->DMRvcL == 0) - { - state->HYTL = state->H; - k = state->H; - k = k << 8; - k = k | ((k >> 40) & 0xFF); - state->HYTL = k; + int pos = 0; + + unsigned long long int k1 = state->K1; + unsigned long long int k2 = state->K2; + unsigned long long int k3 = state->K3; + unsigned long long int k4 = state->K4; + + int T_Key[256] = {0}; + int pN[882] = {0}; + + int len = 0; + + if (k2 == 0) + { + len = 39; + k1 = k1 << 24; + } + if (k2 != 0) + { + len = 127; + } + if (k4 != 0) + { + len = 255; } - k = state->HYTL; - for(short int j = 0; j < 48; j++) - { - x = ( ((k << j) & 0x800000000000) >> 47 ); - ambe_d[j] ^= x; - } + for (i = 0; i < 64; i++) + { + T_Key[i] = ( ((k1 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+64] = ( ((k2 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+128] = ( ((k3 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+192] = ( ((k4 << i) & 0x8000000000000000) >> 63 ); + } - k = k << 1; - msb = (k >> 32) & 0xFFFF; //new MSB - k = (k << 8) & 0xFFFFFFFF0000; - k = k | msb; + for (i = 0; i < 882; i++) + { + pN[i] = T_Key[pos]; + pos++; + if (pos > len) + { + pos = 0; + } + } - state->HYTL = k; + pos = state->DMRvcL * 49; + for(i = 0; i < 49; i++) + { + ambe_d[i] ^= pN[pos]; + pos++; + } state->DMRvcL++; - } mbe_processAmbe2450Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, @@ -289,7 +332,6 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a mbe_demodulateAmbe3600x2450Data (ambe_fr); state->errs2R += mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d); - if (state->K > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x10) { k = Pr[state->K]; @@ -301,34 +343,60 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a } } - if (state->H > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) + if (state->K1 > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) { - unsigned long long int msb = 0; - if (state->DMRvcR == 0) - { - state->HYTR = state->H; - k = state->H; - k = k << 8; - k = k | ((k >> 40) & 0xFF); - state->HYTR = k; + int pos = 0; + + unsigned long long int k1 = state->K1; + unsigned long long int k2 = state->K2; + unsigned long long int k3 = state->K3; + unsigned long long int k4 = state->K4; + + int T_Key[256] = {0}; + int pN[882] = {0}; + + int len = 0; + + if (k2 == 0) + { + len = 39; + k1 = k1 << 24; + } + if (k2 != 0) + { + len = 127; + } + if (k4 != 0) + { + len = 255; } - k = state->HYTR; - for(short int j = 0; j < 48; j++) - { - x = ( ((k << j) & 0x800000000000) >> 47 ); - ambe_d[j] ^= x; - } + for (i = 0; i < 64; i++) + { + T_Key[i] = ( ((k1 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+64] = ( ((k2 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+128] = ( ((k3 << i) & 0x8000000000000000) >> 63 ); + T_Key[i+192] = ( ((k4 << i) & 0x8000000000000000) >> 63 ); + } - k = k << 1; - msb = (k >> 32) & 0xFFFF; - k = (k << 8) & 0xFFFFFFFF0000; - k = k | msb; + for (i = 0; i < 882; i++) + { + pN[i] = T_Key[pos]; + pos++; + if (pos > len) + { + pos = 0; + } + } - state->HYTR = k; + pos = state->DMRvcR * 49; + for(i = 0; i < 49; i++) + { + ambe_d[i] ^= pN[pos]; + pos++; + } state->DMRvcR++; - } mbe_processAmbe2450Dataf (state->audio_out_temp_bufR, &state->errsR, &state->errs2R, state->err_strR, diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index 2c3cf4b..fd1754f 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -206,10 +206,10 @@ char *choices[] = { "Decode NXDN96", "Decode X2-TDMA*", "Toggle Signal Inversion", - "Privacy Key Entry", //spacer + "Privacy Key Entry", "Reset Call History", - "Enable Payloads to Console", - "Disable Payloads to Console", + "Toggle Payloads to Console", + " ", //spacer "Input & Output Options", "LRRP Data to File", "Exit DSD-FME", @@ -802,16 +802,15 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) { state->payload_keyid = 0; state->payload_keyidR = 0; - // state->K = 0; - // state->H = 0; short int option = 0; - entry_win = newwin(9, WIDTH+6, starty+10, startx+10); + entry_win = newwin(10, WIDTH+6, starty+10, startx+10); box (entry_win, 0, 0); mvwprintw(entry_win, 2, 2, "Key Type Selection"); mvwprintw(entry_win, 3, 2, " "); - mvwprintw(entry_win, 4, 2, "1 - DMRA Privacy "); - mvwprintw(entry_win, 5, 2, "2 - 'Tera Privacy "); - mvwprintw(entry_win, 6, 3, " "); + mvwprintw(entry_win, 4, 2, "1 - DMRA Privacy "); + mvwprintw(entry_win, 5, 2, "2 - **tera Privacy "); + mvwprintw(entry_win, 6, 2, "3 - NXDN Scrambler "); + mvwprintw(entry_win, 7, 3, " "); echo(); refresh(); wscanw(entry_win, "%d", &option); @@ -820,6 +819,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) opts->dmr_mute_encR = 0; if (option == 1) { + state->K = 0; entry_win = newwin(6, WIDTH+6, starty+10, startx+10); box (entry_win, 0, 0); mvwprintw(entry_win, 2, 2, "DMRA Privacy Key Number (DEC):"); @@ -835,21 +835,71 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) } if (option == 2) { - entry_win = newwin(6, WIDTH+6, starty+10, startx+10); + state->K1 = 0; + state->K2 = 0; + state->K3 = 0; + state->K4 = 0; + state->H = 0; + + entry_win = newwin(7, WIDTH+6, starty+10, startx+10); box (entry_win, 0, 0); - mvwprintw(entry_win, 2, 2, "'Tera 10 Key Value (HEX):"); - mvwprintw(entry_win, 3, 3, " "); + mvwprintw(entry_win, 2, 2, " Enter **tera BP Key Value (HEX) "); + mvwprintw(entry_win, 3, 2, " 10 Char or First 16 for 32/64"); + mvwprintw(entry_win, 4, 3, " "); echo(); refresh(); wscanw(entry_win, "%llX", &state->H); noecho(); - if (state->H > 0xFFFFFFFFFF) + state->K1 = state->H; + + entry_win = newwin(7, WIDTH+6, starty+10, startx+10); + box (entry_win, 0, 0); + mvwprintw(entry_win, 2, 2, " Enter **tera BP Key Value 2 (HEX) "); + mvwprintw(entry_win, 3, 2, " Second 16 Chars or Zero"); + mvwprintw(entry_win, 4, 3, " "); + echo(); + refresh(); + wscanw(entry_win, "%llX", &state->K2); + noecho(); + + entry_win = newwin(7, WIDTH+6, starty+10, startx+10); + box (entry_win, 0, 0); + mvwprintw(entry_win, 2, 2, " Enter **tera BP Key Value 3 (HEX) "); + mvwprintw(entry_win, 3, 2, " Third 16 Chars or Zero"); + mvwprintw(entry_win, 4, 3, " "); + echo(); + refresh(); + wscanw(entry_win, "%llX", &state->K3); + noecho(); + + entry_win = newwin(7, WIDTH+6, starty+10, startx+10); + box (entry_win, 0, 0); + mvwprintw(entry_win, 2, 2, " Enter **tera BP Key Value 4 (HEX) "); + mvwprintw(entry_win, 3, 2, " Fourth 16 Chars or Zero"); + mvwprintw(entry_win, 4, 3, " "); + echo(); + refresh(); + wscanw(entry_win, "%llX", &state->K4); + noecho(); + + } + if (option == 3) + { + state->R = 0; + entry_win = newwin(6, WIDTH+6, starty+10, startx+10); + box (entry_win, 0, 0); + mvwprintw(entry_win, 2, 2, "NXDN Scrambler Key Value (DEC):"); + mvwprintw(entry_win, 3, 3, " "); + echo(); + refresh(); + wscanw(entry_win, "%lld", &state->R); + noecho(); + if (state->K > 0x7FFF) { - state->H = 0xFFFFFFFFFF; + state->K = 0x7FFF; } } - - if (state->K == 0 && state->H == 0) + if (state->K == 0 && state->K1 == 0) { opts->dmr_mute_encL = 1; opts->dmr_mute_encR = 1; @@ -1156,15 +1206,22 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) } } - if (choice == 15) //turn on payload printing + if (choice == 15) //toggle payload printing { - opts->payload = 1; - fprintf(stderr, "Payload on\n"); + if (opts->payload == 0) + { + opts->payload = 1; + fprintf(stderr, "Payload on\n"); + } + else + { + opts->payload = 0; + fprintf(stderr, "Payload Off\n"); + } } - if (choice == 16) //turn off payload printing + if (choice == 16) { - opts->payload = 0; - fprintf(stderr, "Payload Off\n"); + } if (choice == 18) { @@ -1746,6 +1803,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) printw ("Scrambler "); attroff(COLOR_PAIR(2)); attron(COLOR_PAIR(3)); + if (state->R != 0) + { + //printw ("\n| "); + attron(COLOR_PAIR(1)); + printw ("KEY VALUE: [%05lld] ", state->R ); + printw ("SEED: [%04llX]", state->payload_miN); + attron(COLOR_PAIR(3)); + } } if (state->nxdn_cipher_type == 0x2 && state->carrier == 1) { @@ -1855,7 +1920,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if(state->dmrburstL == 16 && state->payload_algid == 0 && state->H > 0 && state->dmr_fid == 0x68 && ((state->dmr_so & 0xCF) == 0x40) ) { attron(COLOR_PAIR(1)); - printw ("**'Tera Pr Key [%010llX] ", state->H); + printw ("**tera Pr Key [%010llX] ", state->H); attroff(COLOR_PAIR(1)); attron(COLOR_PAIR(3)); } @@ -1963,7 +2028,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if(state->dmrburstR == 16 && state->payload_algidR == 0 && state->H > 0 && ((state->dmr_soR & 0xCF) == 0x40) && state->dmr_fidR == 0x68) { attron(COLOR_PAIR(1)); - printw ("**'Tera Pr Key [%010llX] ", state->H); + printw ("**tera Pr Key [%010llX] ", state->H); attroff(COLOR_PAIR(1)); attron(COLOR_PAIR(3)); } diff --git a/src/nxdn_lib.c b/src/nxdn_lib.c index 5b3fea1..8b48381 100644 --- a/src/nxdn_lib.c +++ b/src/nxdn_lib.c @@ -775,10 +775,17 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message) { fprintf(stderr, "Key ID %u - ", KeyID & 0xFF); - //fprintf (stderr, "%s", KNRM); + fprintf (stderr, "%s", KNRM); //state->nxdn_key = (KeyID & 0xFF); } + if (state->nxdn_cipher_type == 0x01 && state->R > 0) //scrambler + { + fprintf (stderr, "%s", KYEL); + fprintf(stderr, "Value: %05lld", state->R); + fprintf (stderr, "%s", KNRM); + } + if(state->NxdnElementsContent.VCallCrcIsGood) { if ( (SourceUnitID & 0xFFFF) > 0 ) @@ -790,15 +797,6 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message) } //fprintf(stderr, "(CRC OK) "); } - //set enc bit here so we can tell playSynthesizedVoice whether or not to play enc traffic - if (state->nxdn_cipher_type != 0) - { - state->dmr_encL = 1; - } - if (state->nxdn_cipher_type == 0) - { - state->dmr_encL = 0; - } //fprintf(stderr, " (OK) - "); else { @@ -806,6 +804,15 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message) fprintf(stderr, "(CRC ERR) "); fprintf (stderr, "%s", KNRM); } + //set enc bit here so we can tell playSynthesizedVoice whether or not to play enc traffic + if (state->nxdn_cipher_type != 0) + { + state->dmr_encL = 1; + } + if (state->nxdn_cipher_type == 0 || state->R != 0) + { + state->dmr_encL = 0; + } //fprintf(stderr, "\nFull Message = %016llX ", FullMessage); } /* End NXDN_decode_VCALL() */ @@ -1662,7 +1669,24 @@ void ProcessNxdnRTCHFrame(dsd_opts * opts, dsd_state * state, uint8_t Inverted) } } /* End ProcessNxdnRTCHFrame() */ +void LFSRN(char * BufferIn, char * BufferOut, dsd_state * state) +{ + int i; + int lfsr; + int pN[49] = {0}; + int bit = 0; + lfsr = state->payload_miN & 0x7FFF; + for (i = 0; i < 49; i++) + { + pN[i] = lfsr & 0x1; + bit = ( (lfsr >> 1) ^ (lfsr >> 0) ) & 1; + lfsr = ( (lfsr >> 1 ) | (bit << 14) ); + BufferOut[i] = BufferIn[i] ^ pN[i]; + } + + state->payload_miN = lfsr & 0x7FFF; +} /* End of file */ diff --git a/src/nxdn_voice.c b/src/nxdn_voice.c index ffc454e..c212145 100644 --- a/src/nxdn_voice.c +++ b/src/nxdn_voice.c @@ -159,6 +159,10 @@ void processNXDNVoice (dsd_opts * opts, dsd_state * state) if(PartOfFrame == 3) { /* Reset all CRCs of the SACCH */ + if (state->R > 0 && state->nxdn_cipher_type == 0x1) + { + state->payload_miN = state->R; + } for(i = 0; i < 4; i++) state->NxdnSacchRawPart[i].CrcIsGood = 0; }