mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-12 16:57:23 -05:00
639 lines
20 KiB
C
639 lines
20 KiB
C
/*
|
|
* Copyright (C) 2010 DSD Author
|
|
* GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0)
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
|
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include "dsd.h"
|
|
#if !defined(NULL)
|
|
#define NULL 0
|
|
#endif
|
|
|
|
#include "p25p1_check_nid.h"
|
|
|
|
void
|
|
printFrameInfo (dsd_opts * opts, dsd_state * state)
|
|
{
|
|
|
|
int level;
|
|
|
|
level = (int) state->max / 164;
|
|
if (opts->verbose > 0)
|
|
{
|
|
//fprintf (stderr,"inlvl: %2i%% ", level);
|
|
}
|
|
if (state->nac != 0)
|
|
{
|
|
fprintf (stderr, "%s", KCYN);
|
|
fprintf (stderr,"nac: [%4X] ", state->nac);
|
|
fprintf (stderr, "%s", KNRM);
|
|
}
|
|
|
|
if (opts->verbose > 1)
|
|
{
|
|
fprintf (stderr, "%s", KGRN);
|
|
fprintf (stderr,"src: [%8i] ", state->lastsrc);
|
|
fprintf (stderr, "%s", KNRM);
|
|
}
|
|
fprintf (stderr, "%s", KGRN);
|
|
fprintf (stderr,"tg: [%5i] ", state->lasttg);
|
|
fprintf (stderr, "%s", KNRM);
|
|
}
|
|
|
|
void
|
|
processFrame (dsd_opts * opts, dsd_state * state)
|
|
{
|
|
|
|
int i, j, dibit;
|
|
char duid[3];
|
|
char nac[13];
|
|
int level;
|
|
|
|
char status_0;
|
|
char bch_code[63];
|
|
int index_bch_code;
|
|
unsigned char parity;
|
|
char v;
|
|
int new_nac;
|
|
char new_duid[3];
|
|
int check_result;
|
|
|
|
nac[12] = 0;
|
|
duid[2] = 0;
|
|
j = 0;
|
|
|
|
if (state->rf_mod == 1)
|
|
{
|
|
state->maxref = (int)(state->max * 0.80F);
|
|
state->minref = (int)(state->min * 0.80F);
|
|
}
|
|
else
|
|
{
|
|
state->maxref = state->max;
|
|
state->minref = state->min;
|
|
}
|
|
|
|
//NXDN FSW
|
|
if ((state->synctype == 28) || (state->synctype == 29))
|
|
{
|
|
//MBEout restored, is not handled internally by nxdn_frame.c
|
|
nxdn_frame (opts, state);
|
|
return;
|
|
}
|
|
else if ((state->synctype == 6) || (state->synctype == 7))
|
|
{
|
|
state->nac = 0;
|
|
state->lastsrc = 0;
|
|
state->lasttg = 0;
|
|
if (opts->errorbars == 1)
|
|
{
|
|
if (opts->verbose > 0)
|
|
{
|
|
level = (int) state->max / 164;
|
|
//fprintf (stderr,"inlvl: %2i%% ", level);
|
|
}
|
|
}
|
|
state->nac = 0;
|
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
|
{
|
|
openMbeOutFile (opts, state); //dstar ambe files are read back incorrectly, need to change file extension to differentiate when doing a playback
|
|
}
|
|
sprintf (state->fsubtype, " VOICE ");
|
|
processDSTAR (opts, state);
|
|
return;
|
|
}
|
|
else if ((state->synctype == 18) || (state->synctype == 19))
|
|
{
|
|
state->nac = 0;
|
|
state->lastsrc = 0;
|
|
state->lasttg = 0;
|
|
if (opts->errorbars == 1)
|
|
{
|
|
if (opts->verbose > 0)
|
|
{
|
|
level = (int) state->max / 164;
|
|
//fprintf (stderr,"inlvl: %2i%% ", level);
|
|
}
|
|
}
|
|
state->nac = 0;
|
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
|
{
|
|
openMbeOutFile (opts, state); //dstar ambe files are read back incorrectly, need to change file extension to differentiate when doing a playback
|
|
}
|
|
sprintf (state->fsubtype, " DATA ");
|
|
processDSTAR_HD (opts, state);
|
|
return;
|
|
}
|
|
//Start DMR Types
|
|
else if ((state->synctype >= 10) && (state->synctype <= 13) || (state->synctype == 32) || (state->synctype == 33) || (state->synctype == 34) ) //32-34 DMR MS and RC
|
|
{
|
|
|
|
//print manufacturer strings to branding, disabled 0x10 moto other systems can use that fid set
|
|
//0x06 is trident, but when searching, apparently, they developed con+, but was bought by moto?
|
|
if (state->dmr_mfid == 0x10) ; //sprintf (state->dmr_branding, "%s", "Motorola");
|
|
else if (state->dmr_mfid == 0x68) sprintf (state->dmr_branding, "%s", " Hytera");
|
|
else if (state->dmr_mfid == 0x58) sprintf (state->dmr_branding, "%s", " Tait");
|
|
|
|
//disabling these due to random data decodes setting an odd mfid, could be legit, but only for that one packet?
|
|
//or, its just a decode error somewhere
|
|
// else if (state->dmr_mfid == 0x20) sprintf (state->dmr_branding, "%s", "JVC Kenwood");
|
|
// else if (state->dmr_mfid == 0x04) sprintf (state->dmr_branding, "%s", "Flyde Micro");
|
|
// else if (state->dmr_mfid == 0x05) sprintf (state->dmr_branding, "%s", "PROD-EL SPA");
|
|
// else if (state->dmr_mfid == 0x06) sprintf (state->dmr_branding, "%s", "Motorola"); //trident/moto con+
|
|
// else if (state->dmr_mfid == 0x07) sprintf (state->dmr_branding, "%s", "RADIODATA");
|
|
// else if (state->dmr_mfid == 0x08) sprintf (state->dmr_branding, "%s", "Hytera");
|
|
// else if (state->dmr_mfid == 0x09) sprintf (state->dmr_branding, "%s", "ASELSAN");
|
|
// else if (state->dmr_mfid == 0x0A) sprintf (state->dmr_branding, "%s", "Kirisun");
|
|
// else if (state->dmr_mfid == 0x0B) sprintf (state->dmr_branding, "%s", "DMR Association");
|
|
// else if (state->dmr_mfid == 0x13) sprintf (state->dmr_branding, "%s", "EMC S.P.A.");
|
|
// else if (state->dmr_mfid == 0x1C) sprintf (state->dmr_branding, "%s", "EMC S.P.A.");
|
|
// else if (state->dmr_mfid == 0x33) sprintf (state->dmr_branding, "%s", "Radio Activity");
|
|
// else if (state->dmr_mfid == 0x3C) sprintf (state->dmr_branding, "%s", "Radio Activity");
|
|
// else if (state->dmr_mfid == 0x77) sprintf (state->dmr_branding, "%s", "Vertex Standard");
|
|
|
|
//disable so radio id doesn't blink in and out during ncurses and aggressive_framesync
|
|
state->nac = 0;
|
|
|
|
if (opts->errorbars == 1)
|
|
{
|
|
if (opts->verbose > 0)
|
|
{
|
|
level = (int) state->max / 164;
|
|
//fprintf (stderr,"inlvl: %2i%% ", level);
|
|
}
|
|
}
|
|
if ( (state->synctype == 11) || (state->synctype == 12) || (state->synctype == 32) ) //DMR Voice Modes
|
|
{
|
|
|
|
sprintf (state->fsubtype, " VOICE ");
|
|
if (opts->dmr_stereo == 0 && state->synctype < 32)
|
|
{
|
|
sprintf (state->slot1light, " slot1 ");
|
|
sprintf (state->slot2light, " slot2 ");
|
|
//we can safely open MBE on any MS or mono handling
|
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) openMbeOutFile (opts, state);
|
|
if (opts->p25_trunk == 0) dmrMSBootstrap (opts, state);
|
|
}
|
|
if (opts->dmr_mono == 1 && state->synctype == 32)
|
|
{
|
|
//we can safely open MBE on any MS or mono handling
|
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) openMbeOutFile (opts, state);
|
|
if (opts->p25_trunk == 0) dmrMSBootstrap (opts, state);
|
|
}
|
|
if (opts->dmr_stereo == 1) //opts->dmr_stereo == 1
|
|
{
|
|
state->dmr_stereo = 1; //set the state to 1 when handling pure voice frames
|
|
if (state->synctype > 31 )
|
|
{
|
|
//we can safely open MBE on any MS or mono handling
|
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) openMbeOutFile (opts, state);
|
|
if (opts->p25_trunk == 0) dmrMSBootstrap (opts, state); //bootstrap into MS Bootstrap (voice only)
|
|
}
|
|
else dmrBSBootstrap (opts, state); //bootstrap into BS Bootstrap
|
|
}
|
|
}
|
|
else if ( (state->synctype == 33) || (state->synctype == 34) ) //MS Data and RC data
|
|
{
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
if (opts->mbe_out_fR != NULL) closeMbeOutFileR (opts, state);
|
|
if (opts->p25_trunk == 0) dmrMSData (opts, state);
|
|
}
|
|
else
|
|
{
|
|
if (opts->dmr_stereo == 0)
|
|
{
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
if (opts->mbe_out_fR != NULL) closeMbeOutFileR (opts, state);
|
|
|
|
state->err_str[0] = 0;
|
|
sprintf (state->slot1light, " slot1 ");
|
|
sprintf (state->slot2light, " slot2 ");
|
|
dmr_data_sync (opts, state);
|
|
}
|
|
//switch dmr_stereo to 0 when handling BS data frame syncs with processDMRdata
|
|
if (opts->dmr_stereo == 1)
|
|
{
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
if (opts->mbe_out_fR != NULL) closeMbeOutFileR (opts, state);
|
|
|
|
state->dmr_stereo = 0; //set the state to zero for handling pure data frames
|
|
sprintf (state->slot1light, " slot1 ");
|
|
sprintf (state->slot2light, " slot2 ");
|
|
dmr_data_sync (opts, state);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
//X2-TDMA
|
|
else if ((state->synctype >= 2) && (state->synctype <= 5))
|
|
{
|
|
state->nac = 0;
|
|
if (opts->errorbars == 1)
|
|
{
|
|
printFrameInfo (opts, state);
|
|
}
|
|
if ((state->synctype == 3) || (state->synctype == 4))
|
|
{
|
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
|
{
|
|
openMbeOutFile (opts, state);
|
|
}
|
|
sprintf (state->fsubtype, " VOICE ");
|
|
processX2TDMAvoice (opts, state);
|
|
}
|
|
else
|
|
{
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
state->err_str[0] = 0;
|
|
processX2TDMAdata (opts, state);
|
|
}
|
|
return;
|
|
}
|
|
else if ((state->synctype == 14) || (state->synctype == 15))
|
|
{
|
|
if (opts->errorbars == 1)
|
|
{
|
|
if (opts->verbose > 0)
|
|
{
|
|
level = (int) state->max / 164;
|
|
//fprintf (stderr,"inlvl: %2i%% ", level);
|
|
}
|
|
}
|
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
|
{
|
|
openMbeOutFile (opts, state);
|
|
}
|
|
sprintf (state->fsubtype, " VOICE ");
|
|
processProVoice (opts, state);
|
|
return;
|
|
}
|
|
//edacs
|
|
else if ((state->synctype == 37) || (state->synctype == 38))
|
|
{
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
edacs (opts, state);
|
|
return;
|
|
}
|
|
//ysf
|
|
else if ((state->synctype == 30) || (state->synctype == 31))
|
|
{
|
|
//relocate MBEout to inside frame handling -- Not Working Currently for YSF
|
|
processYSF(opts, state);
|
|
return;
|
|
}
|
|
//M17
|
|
else if ((state->synctype == 16) || (state->synctype == 9) || (state->synctype == 17) || (state->synctype == 8) || (state->synctype == 99) || (state->synctype == 98))
|
|
{
|
|
if (state->synctype == 98 || state->synctype == 99) //preamble only
|
|
skipDibit(opts, state, 8); //skip dibits to prime the demodulator
|
|
else if (state->synctype == 16 || state->synctype == 17)
|
|
processM17STR(opts, state);
|
|
else
|
|
processM17LSF(opts, state);
|
|
return;
|
|
}
|
|
//P25 P2
|
|
else if ((state->synctype == 35) || (state->synctype == 36))
|
|
{
|
|
//relocate MBEout to inside frame handling
|
|
processP2(opts, state);
|
|
return;
|
|
}
|
|
//dPMR
|
|
else if ((state->synctype == 20) || (state->synctype == 24))
|
|
{
|
|
/* dPMR Frame Sync 1 */
|
|
fprintf(stderr, "dPMR Frame Sync 1 ");
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
}
|
|
else if ((state->synctype == 21) || (state->synctype == 25))
|
|
{
|
|
/* dPMR Frame Sync 2 */
|
|
fprintf(stderr, "dPMR Frame Sync 2 ");
|
|
|
|
state->nac = 0;
|
|
state->lastsrc = 0;
|
|
state->lasttg = 0;
|
|
if (opts->errorbars == 1)
|
|
{
|
|
if (opts->verbose > 0)
|
|
{
|
|
level = (int) state->max / 164;
|
|
}
|
|
}
|
|
state->nac = 0;
|
|
|
|
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
|
{
|
|
openMbeOutFile (opts, state);
|
|
}
|
|
sprintf(state->fsubtype, " VOICE ");
|
|
processdPMRvoice (opts, state);
|
|
|
|
return;
|
|
|
|
}
|
|
else if ((state->synctype == 22) || (state->synctype == 26))
|
|
{
|
|
/* dPMR Frame Sync 3 */
|
|
fprintf(stderr, "dPMR Frame Sync 3 ");
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
}
|
|
else if ((state->synctype == 23) || (state->synctype == 27))
|
|
{
|
|
/* dPMR Frame Sync 4 */
|
|
fprintf(stderr, "dPMR Frame Sync 4 ");
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
}
|
|
//dPMR
|
|
else //P25
|
|
{
|
|
// Read the NAC, 12 bits
|
|
j = 0;
|
|
index_bch_code = 0;
|
|
for (i = 0; i < 6; i++)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
|
|
v = 1 & (dibit >> 1); // bit 1
|
|
nac[j] = v + '0';
|
|
j++;
|
|
bch_code[index_bch_code] = v;
|
|
index_bch_code++;
|
|
|
|
v = 1 & dibit; // bit 0
|
|
nac[j] = v + '0';
|
|
j++;
|
|
bch_code[index_bch_code] = v;
|
|
index_bch_code++;
|
|
}
|
|
//this one setting bogus nac data
|
|
// state->nac = strtol (nac, NULL, 2);
|
|
|
|
// Read the DUID, 4 bits
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
duid[i] = dibit + '0';
|
|
|
|
bch_code[index_bch_code] = 1 & (dibit >> 1); // bit 1
|
|
index_bch_code++;
|
|
bch_code[index_bch_code] = 1 & dibit; // bit 0
|
|
index_bch_code++;
|
|
}
|
|
|
|
// Read the BCH data for error correction of NAC and DUID
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
|
|
bch_code[index_bch_code] = 1 & (dibit >> 1); // bit 1
|
|
index_bch_code++;
|
|
bch_code[index_bch_code] = 1 & dibit; // bit 0
|
|
index_bch_code++;
|
|
}
|
|
// Intermission: read the status dibit
|
|
status_0 = getDibit (opts, state) + '0';
|
|
// ... continue reading the BCH error correction data
|
|
for (i = 0; i < 20; i++)
|
|
{
|
|
dibit = getDibit (opts, state);
|
|
|
|
bch_code[index_bch_code] = 1 & (dibit >> 1); // bit 1
|
|
index_bch_code++;
|
|
bch_code[index_bch_code] = 1 & dibit; // bit 0
|
|
index_bch_code++;
|
|
}
|
|
|
|
// Read the parity bit
|
|
dibit = getDibit (opts, state);
|
|
bch_code[index_bch_code] = 1 & (dibit >> 1); // bit 1
|
|
parity = (1 & dibit); // bit 0
|
|
|
|
// Check if the NID is correct
|
|
check_result = check_NID (bch_code, &new_nac, new_duid, parity);
|
|
if (check_result) {
|
|
if (new_nac != state->nac) {
|
|
// NAC fixed by error correction
|
|
state->nac = new_nac;
|
|
if (state->p2_hardset == 0 && new_nac != 0)
|
|
{
|
|
state->p2_cc = new_nac;
|
|
}
|
|
state->debug_header_errors++;
|
|
}
|
|
if (strcmp(new_duid, duid) != 0) {
|
|
// DUID fixed by error correction
|
|
//fprintf (stderr,"Fixing DUID %s -> %s\n", duid, new_duid);
|
|
duid[0] = new_duid[0];
|
|
duid[1] = new_duid[1];
|
|
state->debug_header_errors++;
|
|
}
|
|
} else {
|
|
// Check of NID failed and unable to recover its value
|
|
//fprintf (stderr,"NID error\n");
|
|
duid[0] = 'E';
|
|
duid[1] = 'E';
|
|
state->debug_header_critical_errors++;
|
|
}
|
|
}
|
|
|
|
if (strcmp (duid, "00") == 0)
|
|
{
|
|
// Header Data Unit
|
|
if (opts->errorbars == 1)
|
|
{
|
|
printFrameInfo (opts, state);
|
|
fprintf (stderr," HDU\n");
|
|
}
|
|
if (opts->mbe_out_dir[0] != 0)
|
|
{
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
if (opts->mbe_out_f == NULL) openMbeOutFile (opts, state);
|
|
}
|
|
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
|
|
state->lastp25type = 2;
|
|
state->dmrburstL = 25;
|
|
state->currentslot = 0;
|
|
sprintf (state->fsubtype, " HDU ");
|
|
processHDU (opts, state);
|
|
}
|
|
else if (strcmp (duid, "11") == 0)
|
|
{
|
|
// Logical Link Data Unit 1
|
|
if (opts->errorbars == 1)
|
|
{
|
|
printFrameInfo (opts, state);
|
|
fprintf (stderr," LDU1 ");
|
|
}
|
|
if (opts->mbe_out_dir[0] != 0)
|
|
{
|
|
if (opts->mbe_out_f == NULL)
|
|
{
|
|
openMbeOutFile (opts, state);
|
|
}
|
|
}
|
|
state->lastp25type = 1;
|
|
state->dmrburstL = 26;
|
|
state->currentslot = 0;
|
|
sprintf (state->fsubtype, " LDU1 ");
|
|
state->numtdulc = 0;
|
|
|
|
processLDU1 (opts, state);
|
|
}
|
|
else if (strcmp (duid, "22") == 0)
|
|
{
|
|
// Logical Link Data Unit 2
|
|
state->dmrburstL = 27;
|
|
state->currentslot = 0;
|
|
if (state->lastp25type != 1)
|
|
{
|
|
if (opts->errorbars == 1)
|
|
{
|
|
printFrameInfo (opts, state);
|
|
fprintf (stderr,"\n Ignoring LDU2 not preceeded by LDU1\n");
|
|
}
|
|
state->lastp25type = 0;
|
|
sprintf (state->fsubtype, " ");
|
|
}
|
|
else
|
|
{
|
|
if (opts->errorbars == 1)
|
|
{
|
|
printFrameInfo (opts, state);
|
|
fprintf (stderr," LDU2 ");
|
|
}
|
|
if (opts->mbe_out_dir[0] != 0)
|
|
{
|
|
if (opts->mbe_out_f == NULL)
|
|
{
|
|
openMbeOutFile (opts, state);
|
|
}
|
|
}
|
|
state->lastp25type = 2;
|
|
sprintf (state->fsubtype, " LDU2 ");
|
|
state->numtdulc = 0;
|
|
processLDU2 (opts, state);
|
|
}
|
|
}
|
|
else if (strcmp (duid, "33") == 0)
|
|
{
|
|
// Terminator with subsequent Link Control
|
|
state->dmrburstL = 28;
|
|
if (opts->errorbars == 1)
|
|
{
|
|
printFrameInfo (opts, state);
|
|
fprintf (stderr," TDULC\n");
|
|
}
|
|
if (opts->mbe_out_dir[0] != 0)
|
|
{
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
}
|
|
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
|
|
// state->lasttg = 0;
|
|
// state->lastsrc = 0;
|
|
state->lastp25type = 0;
|
|
state->err_str[0] = 0;
|
|
sprintf (state->fsubtype, " TDULC ");
|
|
state->numtdulc++;
|
|
if ((opts->resume > 0) && (state->numtdulc > opts->resume))
|
|
{
|
|
resumeScan (opts, state);
|
|
}
|
|
processTDULC (opts, state);
|
|
state->err_str[0] = 0;
|
|
}
|
|
else if (strcmp (duid, "03") == 0)
|
|
{
|
|
// Terminator without subsequent Link Control
|
|
state->dmrburstL = 28;
|
|
if (opts->errorbars == 1)
|
|
{
|
|
printFrameInfo (opts, state);
|
|
fprintf (stderr," TDU\n");
|
|
}
|
|
if (opts->mbe_out_dir[0] != 0)
|
|
{
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
}
|
|
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
|
|
state->lasttg = 0;
|
|
state->lastsrc = 0;
|
|
state->lastp25type = 0;
|
|
state->err_str[0] = 0;
|
|
sprintf (state->fsubtype, " TDU ");
|
|
|
|
processTDU (opts, state);
|
|
}
|
|
else if (strcmp (duid, "13") == 0)
|
|
{
|
|
state->dmrburstL = 29;
|
|
if (opts->errorbars == 1)
|
|
{
|
|
printFrameInfo (opts, state);
|
|
fprintf (stderr," TSBK");
|
|
}
|
|
if (opts->mbe_out_dir[0] != 0)
|
|
{
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
if (opts->mbe_out_fR != NULL) closeMbeOutFileR (opts, state);
|
|
}
|
|
if (opts->resume > 0)
|
|
{
|
|
resumeScan (opts, state);
|
|
}
|
|
state->lasttg = 0;
|
|
state->lastsrc = 0;
|
|
state->lastp25type = 3;
|
|
sprintf (state->fsubtype, " TSBK ");
|
|
|
|
processTSBK(opts, state);
|
|
|
|
}
|
|
else if (strcmp (duid, "30") == 0)
|
|
{
|
|
state->dmrburstL = 29;
|
|
if (opts->errorbars == 1)
|
|
{
|
|
printFrameInfo (opts, state);
|
|
fprintf (stderr," MBF\n"); //multi block format PDU
|
|
}
|
|
if (opts->mbe_out_dir[0] != 0)
|
|
{
|
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
|
if (opts->mbe_out_fR != NULL) closeMbeOutFileR (opts, state);
|
|
}
|
|
if (opts->resume > 0)
|
|
{
|
|
resumeScan (opts, state);
|
|
}
|
|
state->lastp25type = 4;
|
|
sprintf (state->fsubtype, " MBF ");
|
|
|
|
processMPDU(opts, state);
|
|
}
|
|
|
|
else
|
|
{
|
|
state->lastp25type = 0;
|
|
sprintf (state->fsubtype, " ");
|
|
if (opts->errorbars == 1)
|
|
{
|
|
printFrameInfo (opts, state);
|
|
// fprintf (stderr," duid:%s *Unknown DUID*\n", duid);
|
|
fprintf (stderr," duid:%s \n", duid); //DUID ERR
|
|
}
|
|
}
|
|
}
|