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]);
|
||||
|
||||
//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 Hamming_7_4_init();
|
||||
|
||||
@@ -2747,7 +2747,7 @@ void ProcessVoiceBurstSync(dsd_opts * opts, dsd_state * state)
|
||||
} /* End ProcessVoiceBurstSync() */
|
||||
|
||||
//LFSR code courtesy of https://github.com/mattames/LFSR/
|
||||
int LFSR(dsd_state * state)
|
||||
void LFSR(dsd_state * state)
|
||||
{
|
||||
|
||||
int lfsr = 0;
|
||||
|
||||
@@ -1156,7 +1156,7 @@ main (int argc, char **argv)
|
||||
break;
|
||||
|
||||
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';
|
||||
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
|
||||
}
|
||||
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");
|
||||
opts.dmr_stereo_wav = 1;
|
||||
openWavOutFileL (&opts, &state); //testing for now, will want to move to per call later
|
||||
openWavOutFileR (&opts, &state); //testing for now, will want to move to per call later
|
||||
openWavOutFileL (&opts, &state);
|
||||
openWavOutFileR (&opts, &state);
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
opts.aggressive_framesync = 0;
|
||||
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);
|
||||
break;
|
||||
|
||||
|
||||
@@ -143,9 +143,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
// 0 +P25p1
|
||||
// 1 -P25p1
|
||||
state->errs = mbe_eccImbe7200x4400C0 (imbe_fr);
|
||||
state->errs2 = state->errs;
|
||||
//state->errs2 = state->errs;
|
||||
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->errs2 = state->errs;
|
||||
//state->errs2 = state->errs;
|
||||
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_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))
|
||||
{
|
||||
|
||||
state->errs = mbe_eccAmbe3600x2450C0 (ambe_fr);
|
||||
state->errs2 = state->errs;
|
||||
//state->errs2 = state->errs;
|
||||
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) ||
|
||||
(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->errs2 = state->errs;
|
||||
//state->errs2 = state->errs;
|
||||
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) ||
|
||||
(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->errs2R = state->errsR;
|
||||
//state->errs2R = state->errsR;
|
||||
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) ||
|
||||
(state->K > 0 && state->M == 1) )
|
||||
|
||||
@@ -65,16 +65,39 @@ int i = 0;
|
||||
char versionstr[25];
|
||||
unsigned long long int call_matrix[33][6];
|
||||
|
||||
/*
|
||||
___)__|_
|
||||
.-*' '*-,
|
||||
/ /| |\ \
|
||||
; /_| |_\ ;
|
||||
; |\ /| ;
|
||||
; | ''--...--'' | ;
|
||||
\ ''---.....--'' /
|
||||
''*-.,_______,.-*' BOO!
|
||||
*/
|
||||
|
||||
// char * FM_bannerN[9] = {
|
||||
// " ESC or Arrow Keys For Menu ",
|
||||
// " ██████╗ ██████╗██████╗ ███████╗███╗ ███╗███████╗ ",
|
||||
// " ██╔══██╗██╔════╝██╔══██╗ ██╔════╝████╗ ████║██╔════╝ ",
|
||||
// " ██║ ██║╚█████╗ ██║ ██║ █████╗ ██╔████╔██║█████╗ ",
|
||||
// " ██║ ██║ ╚═══██╗██║ ██║ ██╔══╝ ██║╚██╔╝██║██╔══╝ ",
|
||||
// " ██████╔╝██████╔╝██████╔╝ ██║ ██║ ╚═╝ ██║███████╗ ",
|
||||
// " ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ",
|
||||
// " ",
|
||||
// " "
|
||||
// };
|
||||
|
||||
char * FM_bannerN[9] = {
|
||||
" ESC or Arrow Keys For Menu ",
|
||||
" ██████╗ ██████╗██████╗ ███████╗███╗ ███╗███████╗ ",
|
||||
" ██╔══██╗██╔════╝██╔══██╗ ██╔════╝████╗ ████║██╔════╝ ",
|
||||
" ██║ ██║╚█████╗ ██║ ██║ █████╗ ██╔████╔██║█████╗ ",
|
||||
" ██║ ██║ ╚═══██╗██║ ██║ ██╔══╝ ██║╚██╔╝██║██╔══╝ ",
|
||||
" ██████╔╝██████╔╝██████╔╝ ██║ ██║ ╚═╝ ██║███████╗ ",
|
||||
" ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ",
|
||||
" ",
|
||||
" "
|
||||
" ESC or Arrow Keys For Menu Happy Halloween! ___)__|_ ",
|
||||
" ██████╗ ██████╗██████╗ ███████╗███╗ ███╗███████╗ .-*' '*-, ",
|
||||
" ██╔══██╗██╔════╝██╔══██╗ ██╔════╝████╗ ████║██╔════╝; /_| |_\\ ;",
|
||||
" ██║ ██║╚█████╗ ██║ ██║ █████╗ ██╔████╔██║█████╗ ; |\\ /| ;",
|
||||
" ██║ ██║ ╚═══██╗██║ ██║ ██╔══╝ ██║╚██╔╝██║██╔══╝ ; | ''--...--'' | ; ",
|
||||
" ██████╔╝██████╔╝██████╔╝ ██║ ██║ ╚═╝ ██║███████╗ \\ ''---.....--'' / ",
|
||||
" ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ''*-.,_______,.-*' ",
|
||||
" Happy Halloween ",
|
||||
" "
|
||||
};
|
||||
|
||||
char * SyncTypes[44] = {
|
||||
@@ -152,8 +175,8 @@ char * DMRBusrtTypes[32] = {
|
||||
"VOICE LDU",
|
||||
"TDU/TDULC",
|
||||
"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)
|
||||
{
|
||||
attron(COLOR_PAIR(6)); //6
|
||||
attron(COLOR_PAIR(1)); //6
|
||||
for (short int i = 0; i < 7; i++)
|
||||
{
|
||||
printw("%s \n", FM_bannerN[i]);
|
||||
}
|
||||
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
|
||||
// printw ("--Build Info------------------------------------------------------------------\n");
|
||||
// printw ("| https://github.com/lwvmobile/dsd-fme/tree/pulseaudio\n"); //http link
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*-------------------------------------------------------------------------------
|
||||
* p25p1_tsbk.c
|
||||
* P25 Trunking Signal Block Handler
|
||||
* P25p1 Trunking Signal Block Handler
|
||||
*
|
||||
* LWVMOBILE
|
||||
* 2022-09 DSD-FME Florida Man Edition
|
||||
* 2022-10 DSD-FME Florida Man Edition
|
||||
*-----------------------------------------------------------------------------*/
|
||||
|
||||
#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 i, j, k, b, x, y;
|
||||
int ec = -2; //error value returned from (block_deinterleave)
|
||||
int checksum = -2; //checksum returned from crc16, 0 is valid, anything else is invalid
|
||||
int skipdibit = 14; //initial status dibit will occur at 14, then add 35 each time it occurs
|
||||
int err = -2; //error value returned from crc16_lb_bridge
|
||||
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,
|
||||
//my observation shows that, as far as I know, only the first block of three is good,
|
||||
//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
|
||||
//Multi-Block PDUs are sent on a different DUID - 0xC (not handled currently)
|
||||
|
||||
//collect three reps of 101 dibits (98 valid dibits with status dibits interlaced)
|
||||
for (j = 0; j < 3; j++)
|
||||
@@ -49,7 +47,7 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
||||
|
||||
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);
|
||||
if (ec != 0)
|
||||
{
|
||||
//fprintf (stderr, "BAD BLOCK DEINTERLEAVE");
|
||||
}
|
||||
if (err != 0)
|
||||
{
|
||||
//fprintf (stderr, "BAD CRC16");
|
||||
}
|
||||
|
||||
//shuffle corrected bits back into tsbk_byte
|
||||
k = 0;
|
||||
@@ -93,9 +82,10 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
||||
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[1] = tsbk_byte[0];
|
||||
PDU[1] = tsbk_byte[0] & 0x3F;
|
||||
PDU[2] = tsbk_byte[2];
|
||||
PDU[3] = tsbk_byte[3];
|
||||
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
|
||||
|
||||
//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);
|
||||
process_MAC_VPDU(opts, state, 0, PDU);
|
||||
@@ -149,7 +139,12 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
||||
|
||||
//reset for next rep
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*-------------------------------------------------------------------------------
|
||||
* p25_p2.c
|
||||
* Phase 2 TDMA Voice Processing
|
||||
* p25p2_frame.c
|
||||
* Phase 2 TDMA Frame Processing
|
||||
*
|
||||
* 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
|
||||
const int c0[24] = {
|
||||
const int c0[25] = {
|
||||
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,
|
||||
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
|
||||
};
|
||||
|
||||
const int c3[24] = {
|
||||
const int c3[15] = {
|
||||
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,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,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;
|
||||
@@ -92,57 +92,49 @@ int sacch_rs[2][132] = {0};
|
||||
//store an entire p2 superframe worth of dibits into a bit buffer
|
||||
void p2_dibit_buffer (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
|
||||
for (int i = 0; i < 2140; i++) //2160 for an entire superframe of dibits - 20 sync dibits
|
||||
//we used to grab 2140 (entire superframe minus sync)
|
||||
//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
|
||||
dibit = getDibit(opts, state);
|
||||
//dibit inversion handled internally by getDibit if sync type is inverted
|
||||
p2bit[i*2] = (dibit >> 1) & 1;
|
||||
p2bit[i*2+1] = (dibit & 1);
|
||||
//symbol capture reading now handled directly by getSymbol and getDibit
|
||||
dibit = getDibit(opts, state);
|
||||
//dibit inversion handled internally by getDibit if sync type is inverted
|
||||
p2bit[i*2] = (dibit >> 1) & 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)
|
||||
{
|
||||
//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)
|
||||
unsigned long long int seed = 0;
|
||||
//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)
|
||||
unsigned long long int seed = 0;
|
||||
|
||||
//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 );
|
||||
|
||||
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++)
|
||||
{
|
||||
//External LFSR in figure 7.1 BBAC
|
||||
for (int i = 0; i < 4320; i++)
|
||||
{
|
||||
//External LFSR in figure 7.1 BBAC
|
||||
|
||||
//assign our scramble bit to the array
|
||||
p2lbit[i] = (seed >> 43) & 0x1;
|
||||
//assign same bit to position +4320 to allow for a rollover with an offset value
|
||||
p2lbit[i+4320] = (seed >> 43) & 0x1;
|
||||
//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;
|
||||
seed = (seed << 1) | bit;
|
||||
}
|
||||
//assign our scramble bit to the array
|
||||
p2lbit[i] = (seed >> 43) & 0x1;
|
||||
//assign same bit to position +4320 to allow for a rollover with an offset value
|
||||
p2lbit[i+4320] = (seed >> 43) & 0x1;
|
||||
//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;
|
||||
seed = (seed << 1) | bit;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4300; i++)
|
||||
{
|
||||
//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)];
|
||||
{
|
||||
//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)];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -363,11 +355,11 @@ void process_SACCHs (dsd_opts * opts, dsd_state * state)
|
||||
void process_ISCH (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
isch = 0;
|
||||
for (int i = 0; i < 40; i++)
|
||||
{
|
||||
isch = isch << 1;
|
||||
isch = isch | p2bit[i+320+(360*framing_counter)];
|
||||
}
|
||||
for (int i = 0; i < 40; i++)
|
||||
{
|
||||
isch = isch << 1;
|
||||
isch = isch | p2bit[i+320+(360*framing_counter)];
|
||||
}
|
||||
|
||||
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;
|
||||
state->p2_vch_chan_num = chan_num;
|
||||
|
||||
//old rules for entire superframe worth
|
||||
//determine where the offset should be by first finding TS 0
|
||||
//this rule doesn't seem to work properly on LCCH,
|
||||
//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;
|
||||
}
|
||||
//additional rule for odd chan number offset,
|
||||
//fixes duke, and no issues with other samples
|
||||
else if (chan_num == 1 && isch_loc == 0)
|
||||
// if (chan_num == 0 && isch_loc == 0)
|
||||
// {
|
||||
// state->p2_scramble_offset = 11 - framing_counter;
|
||||
// }
|
||||
// //find TS1 if TS0 isn't found
|
||||
// else if (chan_num == 1 && isch_loc == 0)
|
||||
// {
|
||||
// state->p2_scramble_offset = 12 - framing_counter;
|
||||
// }
|
||||
|
||||
//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;
|
||||
}
|
||||
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
|
||||
{
|
||||
//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;
|
||||
}
|
||||
|
||||
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[1] = p2bit[1+(ts_counter*360)];
|
||||
p2_duid[2] = p2bit[74+(ts_counter*360)];
|
||||
p2_duid[3] = p2bit[75+(ts_counter*360)];
|
||||
p2_duid[4] = p2bit[244+(ts_counter*360)];
|
||||
p2_duid[5] = p2bit[245+(ts_counter*360)];
|
||||
p2_duid[6] = p2bit[318+(ts_counter*360)];
|
||||
p2_duid[7] = p2bit[319+(ts_counter*360)];
|
||||
p2_duid[0] = p2bit[0+(ts_counter*360)];
|
||||
p2_duid[1] = p2bit[1+(ts_counter*360)];
|
||||
p2_duid[2] = p2bit[74+(ts_counter*360)];
|
||||
p2_duid[3] = p2bit[75+(ts_counter*360)];
|
||||
p2_duid[4] = p2bit[244+(ts_counter*360)];
|
||||
p2_duid[5] = p2bit[245+(ts_counter*360)];
|
||||
p2_duid[6] = p2bit[318+(ts_counter*360)];
|
||||
p2_duid[7] = p2bit[319+(ts_counter*360)];
|
||||
|
||||
//process p2_duid with (8,4,4) encoding/decoding
|
||||
int p2_duid_complete = 0;
|
||||
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 p2_duid with (8,4,4) encoding/decoding
|
||||
int p2_duid_complete = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
process_4V (opts, state);
|
||||
p2_duid_complete = p2_duid_complete << 1;
|
||||
p2_duid_complete = p2_duid_complete | p2_duid[i];
|
||||
}
|
||||
}
|
||||
else if (duid_decoded == 6)
|
||||
{
|
||||
fprintf (stderr, " 2V");
|
||||
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)
|
||||
duid_decoded = duid_lookup[p2_duid_complete];
|
||||
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr,"%s ", getTime());
|
||||
fprintf (stderr, " P25p2 ");
|
||||
|
||||
//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 (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)
|
||||
else if (state->currentslot == 1 && duid_decoded != 3 && duid_decoded != 12)
|
||||
{
|
||||
process_SACCHs(opts, state);
|
||||
fprintf (stderr, "VCH 1 ");
|
||||
}
|
||||
}
|
||||
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)
|
||||
else fprintf (stderr, "VCH S ");
|
||||
|
||||
if (duid_decoded == 0)
|
||||
{
|
||||
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 == 13)
|
||||
{
|
||||
state->p2_is_lcch = 1;
|
||||
process_SACCHc(opts, state);
|
||||
}
|
||||
else if (duid_decoded == 4)
|
||||
{
|
||||
fprintf (stderr, " LCCH Sc"); //w/ scrambling
|
||||
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)
|
||||
else if (duid_decoded == 6)
|
||||
{
|
||||
fprintf (stderr, " 2V");
|
||||
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_2V (opts, state);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
process_SACCHs(opts, state);
|
||||
process_SACCHc(opts, state);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, " DUID ERR %d", duid_decoded);
|
||||
if (state->currentslot == 0) state->dmrburstL = 12;
|
||||
else state->dmrburstR = 12;
|
||||
err_counter++;
|
||||
}
|
||||
if (err_counter > 1) //&& opts->aggressive_framesync == 1
|
||||
{
|
||||
//zero out values when errs accumulate in DUID
|
||||
//most likely cause will be signal drop or tuning away
|
||||
state->payload_algid = 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;
|
||||
else if (duid_decoded == 4)
|
||||
{
|
||||
fprintf (stderr, " LCCH Sc"); //w/ scrambling
|
||||
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)
|
||||
{
|
||||
state->p2_is_lcch = 1;
|
||||
process_SACCHs(opts, state);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, " DUID ERR %d", duid_decoded);
|
||||
if (state->currentslot == 0) state->dmrburstL = 12;
|
||||
else state->dmrburstR = 12;
|
||||
err_counter++;
|
||||
}
|
||||
if (err_counter > 1) //&& opts->aggressive_framesync == 1
|
||||
{
|
||||
//zero out values when errs accumulate in DUID
|
||||
//most likely cause will be signal drop or tuning away
|
||||
state->payload_algid = 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;
|
||||
}
|
||||
//since we are in a while loop, run ncursesPrinter here.
|
||||
if (opts->use_ncurses_terminal == 1)
|
||||
{
|
||||
ncursesPrinter(opts, state);
|
||||
}
|
||||
//add 360 bits to each counter
|
||||
vc_counter = vc_counter + 360;
|
||||
goto END;
|
||||
}
|
||||
//since we are in a while loop, run ncursesPrinter here.
|
||||
if (opts->use_ncurses_terminal == 1)
|
||||
{
|
||||
ncursesPrinter(opts, state);
|
||||
}
|
||||
//add 360 bits to each counter
|
||||
vc_counter = vc_counter + 360;
|
||||
|
||||
//flip slots after each TS processed
|
||||
if (state->currentslot == 0)
|
||||
{
|
||||
state->currentslot = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->currentslot = 0;
|
||||
}
|
||||
|
||||
}
|
||||
END:
|
||||
@@ -800,22 +804,29 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state)
|
||||
void processP2 (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
state->dmr_stereo = 1;
|
||||
state->currentslot = 1;
|
||||
//state->currentslot = 1;
|
||||
|
||||
p2_dibit_buffer (opts, state);
|
||||
|
||||
//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
|
||||
}
|
||||
|
||||
//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
|
||||
process_Frame_Scramble (opts, state);
|
||||
process_Frame_Scramble (opts, state);
|
||||
|
||||
//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->p2_is_lcch = 0;
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
/*-------------------------------------------------------------------------------
|
||||
* p25p2_vpdu.c
|
||||
* Phase 2 Variable PDU Handling
|
||||
* Phase 2 Variable PDU (and TSBK PDU) Handling
|
||||
*
|
||||
* LWVMOBILE
|
||||
* 2022-09 DSD-FME Florida Man Edition
|
||||
* 2022-10 DSD-FME Florida Man Edition
|
||||
*-----------------------------------------------------------------------------*/
|
||||
|
||||
#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++)
|
||||
{
|
||||
|
||||
//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)
|
||||
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);
|
||||
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 == 1)
|
||||
if (ist % 1)
|
||||
{
|
||||
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
|
||||
{
|
||||
//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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user