mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-13 01:07:24 -05:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4a0e2e9f3 | ||
|
|
73f0d5df44 | ||
|
|
b003d0a210 | ||
|
|
83f390ba88 | ||
|
|
c8aafb1be0 |
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
*.[ao]
|
||||||
|
*.so*
|
||||||
|
*.dylib
|
||||||
|
build
|
||||||
@@ -873,7 +873,7 @@ void ProcessReservedData(dsd_opts * opts, dsd_state * state, uint8_t info[196],
|
|||||||
void ProcessUnifiedData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
void ProcessUnifiedData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||||
|
|
||||||
//LFSR code courtesy of https://github.com/mattames/LFSR/
|
//LFSR code courtesy of https://github.com/mattames/LFSR/
|
||||||
int LFSR(dsd_state * state);
|
void LFSR(dsd_state * state);
|
||||||
void LFSRN (char * BufferIn, char * BufferOut, dsd_state * state);
|
void LFSRN (char * BufferIn, char * BufferOut, dsd_state * state);
|
||||||
|
|
||||||
void Hamming_7_4_init();
|
void Hamming_7_4_init();
|
||||||
|
|||||||
@@ -2747,7 +2747,7 @@ void ProcessVoiceBurstSync(dsd_opts * opts, dsd_state * state)
|
|||||||
} /* End ProcessVoiceBurstSync() */
|
} /* End ProcessVoiceBurstSync() */
|
||||||
|
|
||||||
//LFSR code courtesy of https://github.com/mattames/LFSR/
|
//LFSR code courtesy of https://github.com/mattames/LFSR/
|
||||||
int LFSR(dsd_state * state)
|
void LFSR(dsd_state * state)
|
||||||
{
|
{
|
||||||
|
|
||||||
int lfsr = 0;
|
int lfsr = 0;
|
||||||
|
|||||||
@@ -1156,7 +1156,7 @@ main (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'T': //repurposed to TDMA/NXDN Per Call
|
case 'T': //repurposed to TDMA/NXDN Per Call
|
||||||
sprintf (wav_file_directory, "./WAV"); // /wav, or ./wav
|
sprintf (wav_file_directory, "./WAV");
|
||||||
wav_file_directory[1023] = '\0';
|
wav_file_directory[1023] = '\0';
|
||||||
if (stat(wav_file_directory, &st) == -1)
|
if (stat(wav_file_directory, &st) == -1)
|
||||||
{
|
{
|
||||||
@@ -1165,17 +1165,19 @@ main (int argc, char **argv)
|
|||||||
mkdir(wav_file_directory, 0700); //user read write execute, needs execute for some reason or segfault
|
mkdir(wav_file_directory, 0700); //user read write execute, needs execute for some reason or segfault
|
||||||
}
|
}
|
||||||
fprintf (stderr,"XDMA and NXDN Per Call Wav File Saving Enabled. (NCurses Terminal Only)\n");
|
fprintf (stderr,"XDMA and NXDN Per Call Wav File Saving Enabled. (NCurses Terminal Only)\n");
|
||||||
sprintf (opts.wav_out_file, "./WAV/DSD-FME-X1.wav"); // foward slash here, on wav_file_directory?
|
sprintf (opts.wav_out_file, "./WAV/DSD-FME-X1.wav");
|
||||||
sprintf (opts.wav_out_fileR, "./WAV/DSD-FME-X2.wav");
|
sprintf (opts.wav_out_fileR, "./WAV/DSD-FME-X2.wav");
|
||||||
opts.dmr_stereo_wav = 1;
|
opts.dmr_stereo_wav = 1;
|
||||||
openWavOutFileL (&opts, &state); //testing for now, will want to move to per call later
|
openWavOutFileL (&opts, &state);
|
||||||
openWavOutFileR (&opts, &state); //testing for now, will want to move to per call later
|
openWavOutFileR (&opts, &state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'F':
|
case 'F':
|
||||||
opts.aggressive_framesync = 0;
|
opts.aggressive_framesync = 0;
|
||||||
fprintf (stderr, "%s", KYEL);
|
fprintf (stderr, "%s", KYEL);
|
||||||
fprintf (stderr,"DMR Stereo Aggressive Resync Disabled!\n");
|
//fprintf (stderr,"DMR Stereo Aggressive Resync Disabled!\n");
|
||||||
|
fprintf (stderr, "Relax P25 Phase 2 MAC_SIGNAL CRC Checksum Pass/Fail\n");
|
||||||
|
fprintf (stderr, "Relax DMR CACH/Burst FEC Pass/Fail\n");
|
||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -143,9 +143,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
// 0 +P25p1
|
// 0 +P25p1
|
||||||
// 1 -P25p1
|
// 1 -P25p1
|
||||||
state->errs = mbe_eccImbe7200x4400C0 (imbe_fr);
|
state->errs = mbe_eccImbe7200x4400C0 (imbe_fr);
|
||||||
state->errs2 = state->errs;
|
//state->errs2 = state->errs;
|
||||||
mbe_demodulateImbe7200x4400Data (imbe_fr);
|
mbe_demodulateImbe7200x4400Data (imbe_fr);
|
||||||
state->errs2 += mbe_eccImbe7200x4400Data (imbe_fr, imbe_d);
|
state->errs2 = mbe_eccImbe7200x4400Data (imbe_fr, imbe_d);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -170,9 +170,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
{
|
{
|
||||||
|
|
||||||
state->errs = mbe_eccImbe7100x4400C0 (imbe7100_fr);
|
state->errs = mbe_eccImbe7100x4400C0 (imbe7100_fr);
|
||||||
state->errs2 = state->errs;
|
//state->errs2 = state->errs;
|
||||||
mbe_demodulateImbe7100x4400Data (imbe7100_fr);
|
mbe_demodulateImbe7100x4400Data (imbe7100_fr);
|
||||||
state->errs2 += mbe_eccImbe7100x4400Data (imbe7100_fr, imbe_d);
|
state->errs2 = mbe_eccImbe7100x4400Data (imbe7100_fr, imbe_d);
|
||||||
mbe_convertImbe7100to7200(imbe_d); //needs extra conversion step apparently
|
mbe_convertImbe7100to7200(imbe_d); //needs extra conversion step apparently
|
||||||
|
|
||||||
mbe_processImbe4400Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
mbe_processImbe4400Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
||||||
@@ -203,10 +203,11 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
}
|
}
|
||||||
else if ((state->synctype == 8) || (state->synctype == 9))
|
else if ((state->synctype == 8) || (state->synctype == 9))
|
||||||
{
|
{
|
||||||
|
|
||||||
state->errs = mbe_eccAmbe3600x2450C0 (ambe_fr);
|
state->errs = mbe_eccAmbe3600x2450C0 (ambe_fr);
|
||||||
state->errs2 = state->errs;
|
//state->errs2 = state->errs;
|
||||||
mbe_demodulateAmbe3600x2450Data (ambe_fr);
|
mbe_demodulateAmbe3600x2450Data (ambe_fr);
|
||||||
state->errs2 += mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d);
|
state->errs2 = mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d);
|
||||||
|
|
||||||
if ( (state->nxdn_cipher_type == 0x01 && state->R > 0) ||
|
if ( (state->nxdn_cipher_type == 0x01 && state->R > 0) ||
|
||||||
(state->M == 1 && state->R > 0) )
|
(state->M == 1 && state->R > 0) )
|
||||||
@@ -248,9 +249,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
{
|
{
|
||||||
|
|
||||||
state->errs = mbe_eccAmbe3600x2450C0 (ambe_fr);
|
state->errs = mbe_eccAmbe3600x2450C0 (ambe_fr);
|
||||||
state->errs2 = state->errs;
|
//state->errs2 = state->errs;
|
||||||
mbe_demodulateAmbe3600x2450Data (ambe_fr);
|
mbe_demodulateAmbe3600x2450Data (ambe_fr);
|
||||||
state->errs2 += mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d);
|
state->errs2 = mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d);
|
||||||
|
|
||||||
if ( (state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x10) ||
|
if ( (state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x10) ||
|
||||||
(state->K > 0 && state->M == 1) )
|
(state->K > 0 && state->M == 1) )
|
||||||
@@ -343,9 +344,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
{
|
{
|
||||||
|
|
||||||
state->errsR = mbe_eccAmbe3600x2450C0 (ambe_fr);
|
state->errsR = mbe_eccAmbe3600x2450C0 (ambe_fr);
|
||||||
state->errs2R = state->errsR;
|
//state->errs2R = state->errsR;
|
||||||
mbe_demodulateAmbe3600x2450Data (ambe_fr);
|
mbe_demodulateAmbe3600x2450Data (ambe_fr);
|
||||||
state->errs2R += mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d);
|
state->errs2R = mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d);
|
||||||
|
|
||||||
if ( (state->K > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x10) ||
|
if ( (state->K > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x10) ||
|
||||||
(state->K > 0 && state->M == 1) )
|
(state->K > 0 && state->M == 1) )
|
||||||
|
|||||||
@@ -65,16 +65,39 @@ int i = 0;
|
|||||||
char versionstr[25];
|
char versionstr[25];
|
||||||
unsigned long long int call_matrix[33][6];
|
unsigned long long int call_matrix[33][6];
|
||||||
|
|
||||||
|
/*
|
||||||
|
___)__|_
|
||||||
|
.-*' '*-,
|
||||||
|
/ /| |\ \
|
||||||
|
; /_| |_\ ;
|
||||||
|
; |\ /| ;
|
||||||
|
; | ''--...--'' | ;
|
||||||
|
\ ''---.....--'' /
|
||||||
|
''*-.,_______,.-*' BOO!
|
||||||
|
*/
|
||||||
|
|
||||||
|
// char * FM_bannerN[9] = {
|
||||||
|
// " ESC or Arrow Keys For Menu ",
|
||||||
|
// " ██████╗ ██████╗██████╗ ███████╗███╗ ███╗███████╗ ",
|
||||||
|
// " ██╔══██╗██╔════╝██╔══██╗ ██╔════╝████╗ ████║██╔════╝ ",
|
||||||
|
// " ██║ ██║╚█████╗ ██║ ██║ █████╗ ██╔████╔██║█████╗ ",
|
||||||
|
// " ██║ ██║ ╚═══██╗██║ ██║ ██╔══╝ ██║╚██╔╝██║██╔══╝ ",
|
||||||
|
// " ██████╔╝██████╔╝██████╔╝ ██║ ██║ ╚═╝ ██║███████╗ ",
|
||||||
|
// " ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ",
|
||||||
|
// " ",
|
||||||
|
// " "
|
||||||
|
// };
|
||||||
|
|
||||||
char * FM_bannerN[9] = {
|
char * FM_bannerN[9] = {
|
||||||
" ESC or Arrow Keys For Menu ",
|
" ESC or Arrow Keys For Menu Happy Halloween! ___)__|_ ",
|
||||||
" ██████╗ ██████╗██████╗ ███████╗███╗ ███╗███████╗ ",
|
" ██████╗ ██████╗██████╗ ███████╗███╗ ███╗███████╗ .-*' '*-, ",
|
||||||
" ██╔══██╗██╔════╝██╔══██╗ ██╔════╝████╗ ████║██╔════╝ ",
|
" ██╔══██╗██╔════╝██╔══██╗ ██╔════╝████╗ ████║██╔════╝; /_| |_\\ ;",
|
||||||
" ██║ ██║╚█████╗ ██║ ██║ █████╗ ██╔████╔██║█████╗ ",
|
" ██║ ██║╚█████╗ ██║ ██║ █████╗ ██╔████╔██║█████╗ ; |\\ /| ;",
|
||||||
" ██║ ██║ ╚═══██╗██║ ██║ ██╔══╝ ██║╚██╔╝██║██╔══╝ ",
|
" ██║ ██║ ╚═══██╗██║ ██║ ██╔══╝ ██║╚██╔╝██║██╔══╝ ; | ''--...--'' | ; ",
|
||||||
" ██████╔╝██████╔╝██████╔╝ ██║ ██║ ╚═╝ ██║███████╗ ",
|
" ██████╔╝██████╔╝██████╔╝ ██║ ██║ ╚═╝ ██║███████╗ \\ ''---.....--'' / ",
|
||||||
" ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ",
|
" ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ''*-.,_______,.-*' ",
|
||||||
" ",
|
" Happy Halloween ",
|
||||||
" "
|
" "
|
||||||
};
|
};
|
||||||
|
|
||||||
char * SyncTypes[44] = {
|
char * SyncTypes[44] = {
|
||||||
@@ -152,8 +175,8 @@ char * DMRBusrtTypes[32] = {
|
|||||||
"VOICE LDU",
|
"VOICE LDU",
|
||||||
"TDU/TDULC",
|
"TDU/TDULC",
|
||||||
"TSBK",
|
"TSBK",
|
||||||
"MAC_SIGNAL",
|
"MAC SIGNAL",
|
||||||
"MAC_SIGNAL"
|
"MAC SIGNAL"
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1910,13 +1933,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||||||
}
|
}
|
||||||
if (opts->ncurses_compact == 0)
|
if (opts->ncurses_compact == 0)
|
||||||
{
|
{
|
||||||
attron(COLOR_PAIR(6)); //6
|
attron(COLOR_PAIR(1)); //6
|
||||||
for (short int i = 0; i < 7; i++)
|
for (short int i = 0; i < 7; i++)
|
||||||
{
|
{
|
||||||
printw("%s \n", FM_bannerN[i]);
|
printw("%s \n", FM_bannerN[i]);
|
||||||
}
|
}
|
||||||
printw (" https://github.com/lwvmobile/dsd-fme/tree/pulseaudio\n");
|
printw (" https://github.com/lwvmobile/dsd-fme/tree/pulseaudio\n");
|
||||||
printw (" Github Build Version: %s \n", GIT_TAG);
|
//printw (" Github Build Version: %s \n", GIT_TAG);
|
||||||
|
printw (" Github Build Version: %s \n", "1313"); //probably better than the first number I thought of
|
||||||
attroff(COLOR_PAIR(6)); //6
|
attroff(COLOR_PAIR(6)); //6
|
||||||
// printw ("--Build Info------------------------------------------------------------------\n");
|
// printw ("--Build Info------------------------------------------------------------------\n");
|
||||||
// printw ("| https://github.com/lwvmobile/dsd-fme/tree/pulseaudio\n"); //http link
|
// printw ("| https://github.com/lwvmobile/dsd-fme/tree/pulseaudio\n"); //http link
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/*-------------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------------
|
||||||
* p25p1_tsbk.c
|
* p25p1_tsbk.c
|
||||||
* P25 Trunking Signal Block Handler
|
* P25p1 Trunking Signal Block Handler
|
||||||
*
|
*
|
||||||
* LWVMOBILE
|
* LWVMOBILE
|
||||||
* 2022-09 DSD-FME Florida Man Edition
|
* 2022-10 DSD-FME Florida Man Edition
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "dsd.h"
|
#include "dsd.h"
|
||||||
@@ -19,16 +19,14 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
|||||||
int tsbk_decoded_bits[190] = {0}; //decoded bits from tsbk_bytes for sending to crc16_lb_bridge
|
int tsbk_decoded_bits[190] = {0}; //decoded bits from tsbk_bytes for sending to crc16_lb_bridge
|
||||||
int i, j, k, b, x, y;
|
int i, j, k, b, x, y;
|
||||||
int ec = -2; //error value returned from (block_deinterleave)
|
int ec = -2; //error value returned from (block_deinterleave)
|
||||||
int checksum = -2; //checksum returned from crc16, 0 is valid, anything else is invalid
|
int err = -2; //error value returned from crc16_lb_bridge
|
||||||
int skipdibit = 14; //initial status dibit will occur at 14, then add 35 each time it occurs
|
int skipdibit = 14; //initial status dibit will occur at 14, then add 36 each time it occurs
|
||||||
|
|
||||||
|
//Update: Identified Bug in skipdibit incrememnt causing many block deinterleave/crc failures
|
||||||
|
//with correct values set, now we are decoding many more TSBKs
|
||||||
|
//TODO: Don't Print TSBKs/vPDUs unless verbosity levels set higher
|
||||||
//TSBKs are always single block, but up to three can be transmitted in a row,
|
//TSBKs are always single block, but up to three can be transmitted in a row,
|
||||||
//my observation shows that, as far as I know, only the first block of three is good,
|
//Multi-Block PDUs are sent on a different DUID - 0xC (not handled currently)
|
||||||
//and NULL types can contain some amount of garbage, but the CRC is always 00s.
|
|
||||||
//Multi-Block PDUs are sent on a different DUID - 0xC
|
|
||||||
//Best way to proceed for now is going to be to collect all three potentials, and only process on good
|
|
||||||
//de-interleaves AND good CRCs, otherwise, ignore them
|
|
||||||
//The Last Block flag doesn't really seem to apply for some reason (byte 0 0x80), or is always on a garbage block
|
|
||||||
|
|
||||||
//collect three reps of 101 dibits (98 valid dibits with status dibits interlaced)
|
//collect three reps of 101 dibits (98 valid dibits with status dibits interlaced)
|
||||||
for (j = 0; j < 3; j++)
|
for (j = 0; j < 3; j++)
|
||||||
@@ -49,7 +47,7 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
if (i+(j*101) == skipdibit)
|
if (i+(j*101) == skipdibit)
|
||||||
{
|
{
|
||||||
skipdibit += 35;
|
skipdibit += 36; //was set to 35, this was the bug
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -68,16 +66,7 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int err = -2;
|
|
||||||
err = crc16_lb_bridge(tsbk_decoded_bits, 80);
|
err = crc16_lb_bridge(tsbk_decoded_bits, 80);
|
||||||
if (ec != 0)
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "BAD BLOCK DEINTERLEAVE");
|
|
||||||
}
|
|
||||||
if (err != 0)
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "BAD CRC16");
|
|
||||||
}
|
|
||||||
|
|
||||||
//shuffle corrected bits back into tsbk_byte
|
//shuffle corrected bits back into tsbk_byte
|
||||||
k = 0;
|
k = 0;
|
||||||
@@ -93,9 +82,10 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
|||||||
tsbk_byte[i] = byte;
|
tsbk_byte[i] = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
//convert tsbk_byte to PDU and send to vPDU handler...may or may not be entirely compatible,
|
//convert tsbk_byte to PDU and send to vPDU handler
|
||||||
|
//...may or may not be entirely compatible,
|
||||||
PDU[0] = 0x07; //P25p1 TSBK Duid 0x07
|
PDU[0] = 0x07; //P25p1 TSBK Duid 0x07
|
||||||
PDU[1] = tsbk_byte[0];
|
PDU[1] = tsbk_byte[0] & 0x3F;
|
||||||
PDU[2] = tsbk_byte[2];
|
PDU[2] = tsbk_byte[2];
|
||||||
PDU[3] = tsbk_byte[3];
|
PDU[3] = tsbk_byte[3];
|
||||||
PDU[4] = tsbk_byte[4];
|
PDU[4] = tsbk_byte[4];
|
||||||
@@ -110,7 +100,7 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
|||||||
PDU[1] = PDU[1] ^ 0x40; //flip bit to make it compatible with MAC_PDUs, i.e. 3D to 7D
|
PDU[1] = PDU[1] ^ 0x40; //flip bit to make it compatible with MAC_PDUs, i.e. 3D to 7D
|
||||||
|
|
||||||
//Don't run NET_STS out of this, or will set wrong NAC/CC
|
//Don't run NET_STS out of this, or will set wrong NAC/CC
|
||||||
if (err == 0 && ec == 0 && PDU[1] != 0x7B && PDU[1] != 0xFB && PDU[1] != 0x49 && PDU[1] != 0x45) //0x49 is telephone grant, 0x46 Unit to Unit Channel Answer Request
|
if (err == 0 && ec == 0 && PDU[1] != 0x7B && PDU[1] != 0x49 && PDU[1] != 0x45) //0x49 is telephone grant, 0x46 Unit to Unit Channel Answer Request (seems bogus)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s",KMAG);
|
fprintf (stderr, "%s",KMAG);
|
||||||
process_MAC_VPDU(opts, state, 0, PDU);
|
process_MAC_VPDU(opts, state, 0, PDU);
|
||||||
@@ -149,7 +139,12 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
//reset for next rep
|
//reset for next rep
|
||||||
ec = -2;
|
ec = -2;
|
||||||
checksum = -2;
|
err = -2;
|
||||||
|
//check for last block bit
|
||||||
|
if ( (tsbk_byte[0] >> 7) == 1 )
|
||||||
|
{
|
||||||
|
j = 4; //set j to break the loop early
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*-------------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------------
|
||||||
* p25_p2.c
|
* p25p2_frame.c
|
||||||
* Phase 2 TDMA Voice Processing
|
* Phase 2 TDMA Frame Processing
|
||||||
*
|
*
|
||||||
* original copyrights for portions used below (OP25 DUID table, MAC len table)
|
* original copyrights for portions used below (OP25 DUID table, MAC len table)
|
||||||
*
|
*
|
||||||
@@ -31,30 +31,30 @@ static const int16_t duid_lookup[256] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//4V and 2V deinterleave schedule
|
//4V and 2V deinterleave schedule
|
||||||
const int c0[24] = {
|
const int c0[25] = {
|
||||||
23,5,22,4,21,3,20,2,19,1,18,0,
|
23,5,22,4,21,3,20,2,19,1,18,0,
|
||||||
17,16,15,14,13,12,11,10,9,7,6
|
17,16,15,14,13,12,11,10,9,8,7,6
|
||||||
};
|
};
|
||||||
|
|
||||||
const int c1[24] = {
|
const int c1[24] = {
|
||||||
10,9,8,7,6,5,22,4,21,3,20,2,
|
10,9,8,7,6,5,22,4,21,3,20,2,
|
||||||
19,1,18,0,17,16,15,14,13,12,11
|
19,1,18,0,17,16,15,14,13,12,11
|
||||||
};
|
};
|
||||||
|
|
||||||
const int c2[24] = {
|
const int c2[12] = {
|
||||||
3,2,1,0,10,9,8,7,6,5,4
|
3,2,1,0,10,9,8,7,6,5,4
|
||||||
};
|
};
|
||||||
|
|
||||||
const int c3[24] = {
|
const int c3[15] = {
|
||||||
13,12,11,10,9,8,7,6,5,4,3,2,1,0
|
13,12,11,10,9,8,7,6,5,4,3,2,1,0
|
||||||
};
|
};
|
||||||
|
|
||||||
const int csubset[72] = {
|
const int csubset[73] = {
|
||||||
0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,
|
0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,
|
||||||
0,0,1,3,0,0,1,3,0,1,1,3,0,1,1,3,
|
0,0,1,3,0,0,1,3,0,1,1,3,0,1,1,3,
|
||||||
0,1,1,3,0,1,1,3,0,1,1,3,0,1,2,3,
|
0,1,1,3,0,1,1,3,0,1,1,3,0,1,2,3,
|
||||||
0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,
|
0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,
|
||||||
0,1,2,3
|
0,1,2,3,0,1,2,3
|
||||||
};
|
};
|
||||||
|
|
||||||
const int *w;
|
const int *w;
|
||||||
@@ -92,57 +92,49 @@ int sacch_rs[2][132] = {0};
|
|||||||
//store an entire p2 superframe worth of dibits into a bit buffer
|
//store an entire p2 superframe worth of dibits into a bit buffer
|
||||||
void p2_dibit_buffer (dsd_opts * opts, dsd_state * state)
|
void p2_dibit_buffer (dsd_opts * opts, dsd_state * state)
|
||||||
{
|
{
|
||||||
|
//we used to grab 2140 (entire superframe minus sync)
|
||||||
for (int i = 0; i < 2140; i++) //2160 for an entire superframe of dibits - 20 sync dibits
|
//now we grab 700 (4 Timeslots minus sync)
|
||||||
|
for (int i = 0; i < 700; i++) //2160 for an entire superframe of dibits - 20 sync dibits
|
||||||
{
|
{
|
||||||
//symbol capture reading now handled directly by getSymbol and getDibit
|
//symbol capture reading now handled directly by getSymbol and getDibit
|
||||||
dibit = getDibit(opts, state);
|
dibit = getDibit(opts, state);
|
||||||
//dibit inversion handled internally by getDibit if sync type is inverted
|
//dibit inversion handled internally by getDibit if sync type is inverted
|
||||||
p2bit[i*2] = (dibit >> 1) & 1;
|
p2bit[i*2] = (dibit >> 1) & 1;
|
||||||
p2bit[i*2+1] = (dibit & 1);
|
p2bit[i*2+1] = (dibit & 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//grab the entire VCH S-ISCH from the buffer and tack it onto the very end of the bitstream for reference?
|
|
||||||
int *dibit_p;
|
|
||||||
dibit_p = state->dibit_buf_p - 20; //rewind 20 dibits
|
|
||||||
for (int i = 2140; i < 2160; i++) //2160 for an entire superframe of dibits (Symbols)
|
|
||||||
{
|
|
||||||
dibit = *dibit_p;
|
|
||||||
dibit_p++;
|
|
||||||
p2bit[i*2] = (dibit >> 1) & 1;
|
|
||||||
p2bit[i*2+1] = (dibit & 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_Frame_Scramble (dsd_opts * opts, dsd_state * state)
|
void process_Frame_Scramble (dsd_opts * opts, dsd_state * state)
|
||||||
{
|
{
|
||||||
//The bits of the scramble sequence corresponding to signal bits that are not scrambled or not used are discarded.
|
//The bits of the scramble sequence corresponding to signal bits that are not scrambled or not used are discarded.
|
||||||
//descramble frame scrambled by LFSR of WACN, SysID, and CC(NAC)
|
//descramble frame scrambled by LFSR of WACN, SysID, and CC(NAC)
|
||||||
unsigned long long int seed = 0;
|
unsigned long long int seed = 0;
|
||||||
|
|
||||||
//below calc is the same as shifting left the required number of bits.
|
//below calc is the same as shifting left the required number of bits.
|
||||||
seed = ( (state->p2_wacn * 16777216) + (state->p2_sysid * 4096) + state->p2_cc );
|
seed = ( (state->p2_wacn * 16777216) + (state->p2_sysid * 4096) + state->p2_cc );
|
||||||
|
|
||||||
unsigned long long int bit = 1; //temp bit for storage during LFSR operation
|
unsigned long long int bit = 1; //temp bit for storage during LFSR operation
|
||||||
|
|
||||||
for (int i = 0; i < 4320; i++)
|
for (int i = 0; i < 4320; i++)
|
||||||
{
|
{
|
||||||
//External LFSR in figure 7.1 BBAC
|
//External LFSR in figure 7.1 BBAC
|
||||||
|
|
||||||
//assign our scramble bit to the array
|
//assign our scramble bit to the array
|
||||||
p2lbit[i] = (seed >> 43) & 0x1;
|
p2lbit[i] = (seed >> 43) & 0x1;
|
||||||
//assign same bit to position +4320 to allow for a rollover with an offset value
|
//assign same bit to position +4320 to allow for a rollover with an offset value
|
||||||
p2lbit[i+4320] = (seed >> 43) & 0x1;
|
p2lbit[i+4320] = (seed >> 43) & 0x1;
|
||||||
//compute our next scramble bit and shift the seed register and append bit to LSB
|
//compute our next scramble bit and shift the seed register and append bit to LSB
|
||||||
bit = ((seed >> 33) ^ (seed >> 19) ^ (seed >> 14) ^ (seed >> 8) ^ (seed >> 3) ^ (seed >> 43)) & 0x1;
|
bit = ((seed >> 33) ^ (seed >> 19) ^ (seed >> 14) ^ (seed >> 8) ^ (seed >> 3) ^ (seed >> 43)) & 0x1;
|
||||||
seed = (seed << 1) | bit;
|
seed = (seed << 1) | bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4300; i++)
|
for (int i = 0; i < 4300; i++)
|
||||||
{
|
{
|
||||||
//offset by 20 for sync, then 360 for each ts frame off from start of superframe
|
//offset by 20 for sync, then 360 for each ts frame off from start of superframe
|
||||||
p2xbit[i] = p2bit[i] ^ p2lbit[i+20+(360*state->p2_scramble_offset)];
|
p2xbit[i] = p2bit[i] ^ p2lbit[i+20+(360*state->p2_scramble_offset)];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -363,11 +355,11 @@ void process_SACCHs (dsd_opts * opts, dsd_state * state)
|
|||||||
void process_ISCH (dsd_opts * opts, dsd_state * state)
|
void process_ISCH (dsd_opts * opts, dsd_state * state)
|
||||||
{
|
{
|
||||||
isch = 0;
|
isch = 0;
|
||||||
for (int i = 0; i < 40; i++)
|
for (int i = 0; i < 40; i++)
|
||||||
{
|
{
|
||||||
isch = isch << 1;
|
isch = isch << 1;
|
||||||
isch = isch | p2bit[i+320+(360*framing_counter)];
|
isch = isch | p2bit[i+320+(360*framing_counter)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isch == 0x575D57F7FF) //S-ISCH frame sync, pass;
|
if (isch == 0x575D57F7FF) //S-ISCH frame sync, pass;
|
||||||
{
|
{
|
||||||
@@ -385,29 +377,40 @@ void process_ISCH (dsd_opts * opts, dsd_state * state)
|
|||||||
int chan_num = (isch_decoded >> 5) & 0x3;
|
int chan_num = (isch_decoded >> 5) & 0x3;
|
||||||
state->p2_vch_chan_num = chan_num;
|
state->p2_vch_chan_num = chan_num;
|
||||||
|
|
||||||
|
//old rules for entire superframe worth
|
||||||
//determine where the offset should be by first finding TS 0
|
//determine where the offset should be by first finding TS 0
|
||||||
//this rule doesn't seem to work properly on LCCH,
|
// if (chan_num == 0 && isch_loc == 0)
|
||||||
//duke always showed a chan 1 loc 0, so offset 12 - frame
|
// {
|
||||||
if (chan_num == 0 && isch_loc == 0)
|
// state->p2_scramble_offset = 11 - framing_counter;
|
||||||
{
|
// }
|
||||||
state->p2_scramble_offset = 11 - framing_counter;
|
// //find TS1 if TS0 isn't found
|
||||||
}
|
// else if (chan_num == 1 && isch_loc == 0)
|
||||||
//additional rule for odd chan number offset,
|
// {
|
||||||
//fixes duke, and no issues with other samples
|
// state->p2_scramble_offset = 12 - framing_counter;
|
||||||
else if (chan_num == 1 && isch_loc == 0)
|
// }
|
||||||
|
|
||||||
|
//new rules for relative position to the only chan 1 we should see
|
||||||
|
if (chan_num == 1 && isch_loc == 0)
|
||||||
{
|
{
|
||||||
state->p2_scramble_offset = 12 - framing_counter;
|
state->p2_scramble_offset = 12 - framing_counter;
|
||||||
}
|
}
|
||||||
|
else if (chan_num == 1 && isch_loc == 1)
|
||||||
|
{
|
||||||
|
state->p2_scramble_offset = 4 - framing_counter;
|
||||||
|
}
|
||||||
|
else if (chan_num == 1 && isch_loc == 2)
|
||||||
|
{
|
||||||
|
state->p2_scramble_offset = 8 - framing_counter;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//if -2(no return value) or -1(fec error)
|
//if -2(no return value) or -1(fec error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// fprintf (stderr, "\n");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -653,140 +656,141 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state)
|
|||||||
return curr;
|
return curr;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ts_counter = 0; ts_counter < 12; ts_counter++)
|
for (ts_counter = 0; ts_counter < 4; ts_counter++) //12
|
||||||
{
|
{
|
||||||
|
|
||||||
p2_duid[0] = p2bit[0+(ts_counter*360)];
|
p2_duid[0] = p2bit[0+(ts_counter*360)];
|
||||||
p2_duid[1] = p2bit[1+(ts_counter*360)];
|
p2_duid[1] = p2bit[1+(ts_counter*360)];
|
||||||
p2_duid[2] = p2bit[74+(ts_counter*360)];
|
p2_duid[2] = p2bit[74+(ts_counter*360)];
|
||||||
p2_duid[3] = p2bit[75+(ts_counter*360)];
|
p2_duid[3] = p2bit[75+(ts_counter*360)];
|
||||||
p2_duid[4] = p2bit[244+(ts_counter*360)];
|
p2_duid[4] = p2bit[244+(ts_counter*360)];
|
||||||
p2_duid[5] = p2bit[245+(ts_counter*360)];
|
p2_duid[5] = p2bit[245+(ts_counter*360)];
|
||||||
p2_duid[6] = p2bit[318+(ts_counter*360)];
|
p2_duid[6] = p2bit[318+(ts_counter*360)];
|
||||||
p2_duid[7] = p2bit[319+(ts_counter*360)];
|
p2_duid[7] = p2bit[319+(ts_counter*360)];
|
||||||
|
|
||||||
//process p2_duid with (8,4,4) encoding/decoding
|
//process p2_duid with (8,4,4) encoding/decoding
|
||||||
int p2_duid_complete = 0;
|
int p2_duid_complete = 0;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
|
||||||
p2_duid_complete = p2_duid_complete << 1;
|
|
||||||
p2_duid_complete = p2_duid_complete | p2_duid[i];
|
|
||||||
}
|
|
||||||
duid_decoded = duid_lookup[p2_duid_complete];
|
|
||||||
|
|
||||||
fprintf (stderr, "\n");
|
|
||||||
fprintf (stderr,"%s ", getTime());
|
|
||||||
fprintf (stderr, " P25p2 ");
|
|
||||||
|
|
||||||
if (state->currentslot == 0)
|
|
||||||
{
|
|
||||||
state->currentslot = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state->currentslot = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//print our VCH channel number, or print S for SACCH since its inverted
|
|
||||||
if (state->currentslot == 0 && duid_decoded != 3 && duid_decoded != 12)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "VCH 0 ");
|
|
||||||
}
|
|
||||||
else if (state->currentslot == 1 && duid_decoded != 3 && duid_decoded != 12)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "VCH 1 ");
|
|
||||||
}
|
|
||||||
else fprintf (stderr, "VCH S ");
|
|
||||||
|
|
||||||
if (duid_decoded == 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, " 4V %d", state->fourv_counter[state->currentslot]+1);
|
|
||||||
if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 &&
|
|
||||||
state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF)
|
|
||||||
{
|
{
|
||||||
process_4V (opts, state);
|
p2_duid_complete = p2_duid_complete << 1;
|
||||||
|
p2_duid_complete = p2_duid_complete | p2_duid[i];
|
||||||
}
|
}
|
||||||
}
|
duid_decoded = duid_lookup[p2_duid_complete];
|
||||||
else if (duid_decoded == 6)
|
|
||||||
{
|
fprintf (stderr, "\n");
|
||||||
fprintf (stderr, " 2V");
|
fprintf (stderr,"%s ", getTime());
|
||||||
if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 &&
|
fprintf (stderr, " P25p2 ");
|
||||||
state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF)
|
|
||||||
|
//print our VCH channel number, or print S for SACCH since its inverted
|
||||||
|
if (state->currentslot == 0 && duid_decoded != 3 && duid_decoded != 12)
|
||||||
{
|
{
|
||||||
process_2V (opts, state);
|
fprintf (stderr, "VCH 0 ");
|
||||||
}
|
}
|
||||||
}
|
else if (state->currentslot == 1 && duid_decoded != 3 && duid_decoded != 12)
|
||||||
else if (duid_decoded == 3)
|
|
||||||
{
|
|
||||||
if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 &&
|
|
||||||
state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF)
|
|
||||||
{
|
{
|
||||||
process_SACCHs(opts, state);
|
fprintf (stderr, "VCH 1 ");
|
||||||
}
|
}
|
||||||
}
|
else fprintf (stderr, "VCH S ");
|
||||||
else if (duid_decoded == 12)
|
|
||||||
{
|
if (duid_decoded == 0)
|
||||||
process_SACCHc(opts, state);
|
|
||||||
}
|
|
||||||
else if (duid_decoded == 15)
|
|
||||||
{
|
|
||||||
process_FACCHc(opts, state);
|
|
||||||
}
|
|
||||||
else if (duid_decoded == 9)
|
|
||||||
{
|
|
||||||
if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 &&
|
|
||||||
state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF)
|
|
||||||
{
|
{
|
||||||
process_FACCHs(opts, state);
|
fprintf (stderr, " 4V %d", state->fourv_counter[state->currentslot]+1);
|
||||||
|
if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 &&
|
||||||
|
state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF)
|
||||||
|
{
|
||||||
|
process_4V (opts, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else if (duid_decoded == 6)
|
||||||
else if (duid_decoded == 13)
|
{
|
||||||
{
|
fprintf (stderr, " 2V");
|
||||||
state->p2_is_lcch = 1;
|
if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 &&
|
||||||
process_SACCHc(opts, state);
|
state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF)
|
||||||
}
|
{
|
||||||
else if (duid_decoded == 4)
|
process_2V (opts, state);
|
||||||
{
|
}
|
||||||
fprintf (stderr, " LCCH Sc"); //w/ scrambling
|
}
|
||||||
if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 &&
|
else if (duid_decoded == 3)
|
||||||
state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF)
|
{
|
||||||
|
if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 &&
|
||||||
|
state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF)
|
||||||
|
{
|
||||||
|
process_SACCHs(opts, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (duid_decoded == 12)
|
||||||
|
{
|
||||||
|
process_SACCHc(opts, state);
|
||||||
|
}
|
||||||
|
else if (duid_decoded == 15)
|
||||||
|
{
|
||||||
|
process_FACCHc(opts, state);
|
||||||
|
}
|
||||||
|
else if (duid_decoded == 9)
|
||||||
|
{
|
||||||
|
if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 &&
|
||||||
|
state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF)
|
||||||
|
{
|
||||||
|
process_FACCHs(opts, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (duid_decoded == 13)
|
||||||
{
|
{
|
||||||
state->p2_is_lcch = 1;
|
state->p2_is_lcch = 1;
|
||||||
process_SACCHs(opts, state);
|
process_SACCHc(opts, state);
|
||||||
}
|
}
|
||||||
}
|
else if (duid_decoded == 4)
|
||||||
else
|
{
|
||||||
{
|
fprintf (stderr, " LCCH Sc"); //w/ scrambling
|
||||||
fprintf (stderr, " DUID ERR %d", duid_decoded);
|
if (state->p2_wacn != 0 && state->p2_cc != 0 && state->p2_sysid != 0 &&
|
||||||
if (state->currentslot == 0) state->dmrburstL = 12;
|
state->p2_wacn != 0xFFFFF && state->p2_cc != 0xFFF && state->p2_sysid != 0xFFF)
|
||||||
else state->dmrburstR = 12;
|
{
|
||||||
err_counter++;
|
state->p2_is_lcch = 1;
|
||||||
}
|
process_SACCHs(opts, state);
|
||||||
if (err_counter > 1) //&& opts->aggressive_framesync == 1
|
}
|
||||||
{
|
}
|
||||||
//zero out values when errs accumulate in DUID
|
else
|
||||||
//most likely cause will be signal drop or tuning away
|
{
|
||||||
state->payload_algid = 0;
|
fprintf (stderr, " DUID ERR %d", duid_decoded);
|
||||||
state->payload_keyid = 0;
|
if (state->currentslot == 0) state->dmrburstL = 12;
|
||||||
state->payload_algidR = 0;
|
else state->dmrburstR = 12;
|
||||||
state->payload_keyidR = 0;
|
err_counter++;
|
||||||
state->lastsrc = 0;
|
}
|
||||||
state->lastsrcR = 0;
|
if (err_counter > 1) //&& opts->aggressive_framesync == 1
|
||||||
state->lasttg = 0;
|
{
|
||||||
state->lasttgR = 0;
|
//zero out values when errs accumulate in DUID
|
||||||
state->p2_is_lcch = 0;
|
//most likely cause will be signal drop or tuning away
|
||||||
state->fourv_counter[0] = 0;
|
state->payload_algid = 0;
|
||||||
state->fourv_counter[1] = 0;
|
state->payload_keyid = 0;
|
||||||
|
state->payload_algidR = 0;
|
||||||
|
state->payload_keyidR = 0;
|
||||||
|
state->lastsrc = 0;
|
||||||
|
state->lastsrcR = 0;
|
||||||
|
state->lasttg = 0;
|
||||||
|
state->lasttgR = 0;
|
||||||
|
state->p2_is_lcch = 0;
|
||||||
|
state->fourv_counter[0] = 0;
|
||||||
|
state->fourv_counter[1] = 0;
|
||||||
|
|
||||||
goto END;
|
goto END;
|
||||||
}
|
}
|
||||||
//since we are in a while loop, run ncursesPrinter here.
|
//since we are in a while loop, run ncursesPrinter here.
|
||||||
if (opts->use_ncurses_terminal == 1)
|
if (opts->use_ncurses_terminal == 1)
|
||||||
{
|
{
|
||||||
ncursesPrinter(opts, state);
|
ncursesPrinter(opts, state);
|
||||||
}
|
}
|
||||||
//add 360 bits to each counter
|
//add 360 bits to each counter
|
||||||
vc_counter = vc_counter + 360;
|
vc_counter = vc_counter + 360;
|
||||||
|
|
||||||
|
//flip slots after each TS processed
|
||||||
|
if (state->currentslot == 0)
|
||||||
|
{
|
||||||
|
state->currentslot = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state->currentslot = 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
END:
|
END:
|
||||||
@@ -800,22 +804,29 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state)
|
|||||||
void processP2 (dsd_opts * opts, dsd_state * state)
|
void processP2 (dsd_opts * opts, dsd_state * state)
|
||||||
{
|
{
|
||||||
state->dmr_stereo = 1;
|
state->dmr_stereo = 1;
|
||||||
state->currentslot = 1;
|
//state->currentslot = 1;
|
||||||
|
|
||||||
p2_dibit_buffer (opts, state);
|
p2_dibit_buffer (opts, state);
|
||||||
|
|
||||||
//look at our ISCH values and determine location in superframe before running frame scramble
|
//look at our ISCH values and determine location in superframe before running frame scramble
|
||||||
for (framing_counter = 0; framing_counter < 11; framing_counter++) //11, or 12
|
for (framing_counter = 0; framing_counter < 4; framing_counter++) //12
|
||||||
{
|
{
|
||||||
process_ISCH (opts, state); //run ISCH in here so we know when to start descramble offset
|
process_ISCH (opts, state); //run ISCH in here so we know when to start descramble offset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set initial current slot depending on offset value
|
||||||
|
if (state->p2_scramble_offset % 2)
|
||||||
|
{
|
||||||
|
state->currentslot = 0;
|
||||||
|
}
|
||||||
|
else state->currentslot = 1;
|
||||||
|
|
||||||
//frame_scramble runs lfsr and creates an array of unscrambled bits to pull from
|
//frame_scramble runs lfsr and creates an array of unscrambled bits to pull from
|
||||||
process_Frame_Scramble (opts, state);
|
process_Frame_Scramble (opts, state);
|
||||||
|
|
||||||
//process DUID will run through all collected frames and handle them appropriately
|
//process DUID will run through all collected frames and handle them appropriately
|
||||||
process_P2_DUID (opts, state);
|
process_P2_DUID (opts, state);
|
||||||
state->dmr_stereo = 0;
|
state->dmr_stereo = 0;
|
||||||
state->p2_is_lcch = 0;
|
state->p2_is_lcch = 0;
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
/*-------------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------------
|
||||||
* p25p2_vpdu.c
|
* p25p2_vpdu.c
|
||||||
* Phase 2 Variable PDU Handling
|
* Phase 2 Variable PDU (and TSBK PDU) Handling
|
||||||
*
|
*
|
||||||
* LWVMOBILE
|
* LWVMOBILE
|
||||||
* 2022-09 DSD-FME Florida Man Edition
|
* 2022-10 DSD-FME Florida Man Edition
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "dsd.h"
|
#include "dsd.h"
|
||||||
@@ -77,6 +77,70 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//New PDUs added below here as of 10-23-2022
|
||||||
|
|
||||||
|
//SNDCP Data Channel Announcement
|
||||||
|
if (MAC[1+len_a] == 0xD6)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "\n SNDCP Data Channel Announcement ");
|
||||||
|
}
|
||||||
|
|
||||||
|
//MFID90 Group Regroup Add Command
|
||||||
|
if (MAC[1+len_a] == 0x81) //needs MAC message len update, may work same as explicit enc regroup?
|
||||||
|
{
|
||||||
|
fprintf (stderr, "\n MFID90 Group Regroup Add Command ");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Authentication Response - Abbreviated
|
||||||
|
if (MAC[1+len_a] == 0x78)
|
||||||
|
{
|
||||||
|
int res1 = 0; //don't really care about this value, just setting it to zero
|
||||||
|
int source = (MAC[8+len_a] << 16) | (MAC[9+len_a] << 8) | MAC[10+len_a];
|
||||||
|
fprintf (stderr, "\n Authentication Response - Abbreviated \n");
|
||||||
|
fprintf (stderr, " Source [%08d][%06X] ", source, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Authentication Response - Extended
|
||||||
|
if (MAC[1+len_a] == 0xF8)
|
||||||
|
{
|
||||||
|
//only partial data will print on this, do we really care about the SUID?
|
||||||
|
int source = (MAC[5+len_a] << 16) | (MAC[6+len_a] << 8) | MAC[7+len_a];
|
||||||
|
fprintf (stderr, "\n Authentication Response - Extended \n");
|
||||||
|
fprintf (stderr, " Source [%08d][%06X] ", source, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
//RFSS Status Broadcast - Implicit
|
||||||
|
if (MAC[1+len_a] == 0x7A)
|
||||||
|
{
|
||||||
|
int lra = MAC[2+len_a];
|
||||||
|
int lsysid = ((MAC[3+len_a] & 0xF) << 8) | MAC[4+len_a];
|
||||||
|
int rfssid = MAC[5+len_a];
|
||||||
|
int siteid = MAC[6+len_a];
|
||||||
|
int channel = (MAC[7+len_a] << 8) | MAC[8+len_a];
|
||||||
|
int sysclass = MAC[9+len_a];
|
||||||
|
fprintf (stderr, "\n RFSS Status Broadcast - Implicit \n");
|
||||||
|
fprintf (stderr, " LRA [%02X] SYSID [%03X] RFSS ID [%02X] SITE ID [%02X] CHAN [%04X] SSC [%02X] ", lra, lsysid, rfssid, siteid, channel, sysclass);
|
||||||
|
process_channel_to_freq (opts, state, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
//RFSS Status Broadcast - Explicit
|
||||||
|
if (MAC[1+len_a] == 0xFA)
|
||||||
|
{
|
||||||
|
int lra = MAC[2+len_a];
|
||||||
|
int lsysid = ((MAC[3+len_a] & 0xF) << 8) | MAC[4+len_a];
|
||||||
|
int rfssid = MAC[5+len_a];
|
||||||
|
int siteid = MAC[6+len_a];
|
||||||
|
int channelt = (MAC[7+len_a] << 8) | MAC[8+len_a];
|
||||||
|
int channelr = (MAC[9+len_a] << 8) | MAC[10+len_a];
|
||||||
|
int sysclass = MAC[11+len_a];
|
||||||
|
fprintf (stderr, "\n RFSS Status Broadcast - Explicit \n");
|
||||||
|
fprintf (stderr, " LRA [%02X] SYSID [%03X] RFSS ID [%02X] SITE ID [%02X]\n CHAN-T [%04X] CHAN-R [%02X] SSC [%02X] ", lra, lsysid, rfssid, siteid, channelt, channelr, sysclass);
|
||||||
|
process_channel_to_freq (opts, state, channelt);
|
||||||
|
process_channel_to_freq (opts, state, channelr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//End New PDUs added
|
||||||
|
|
||||||
//Group Voice Channel Grant (GRP_V_CH_GRANT)
|
//Group Voice Channel Grant (GRP_V_CH_GRANT)
|
||||||
if (MAC[1+len_a] == 0x40)
|
if (MAC[1+len_a] == 0x40)
|
||||||
{
|
{
|
||||||
@@ -156,7 +220,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
year, month, day, hour, min, seconds);
|
year, month, day, hour, min, seconds);
|
||||||
fprintf (stderr, " Local Time Offset: %.01f Hours;", offhour);
|
fprintf (stderr, " Local Time Offset: %.01f Hours;", offhour);
|
||||||
//if ist bit is set, then time on system may be considered invalid (i.e., no external time sync)
|
//if ist bit is set, then time on system may be considered invalid (i.e., no external time sync)
|
||||||
if (ist == 1)
|
if (ist % 1)
|
||||||
{
|
{
|
||||||
fprintf (stderr, " Invalid System Time ");
|
fprintf (stderr, " Invalid System Time ");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
|
|||||||
if (SMAC[1] == 0x0) //NULL PDU Check, pass if NULL type
|
if (SMAC[1] == 0x0) //NULL PDU Check, pass if NULL type
|
||||||
{
|
{
|
||||||
//fprintf (stderr, " NULL ");
|
//fprintf (stderr, " NULL ");
|
||||||
|
state->p2_is_lcch = 0; //turn flag off here
|
||||||
|
goto END_SMAC;
|
||||||
}
|
}
|
||||||
else //permit MAC_SIGNAL on CRC ERR if -F option called
|
else //permit MAC_SIGNAL on CRC ERR if -F option called
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user