diff --git a/include/dsd.h b/include/dsd.h index dc5ea31..cf87d51 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -752,6 +752,14 @@ typedef struct int edacs_vc_lcn; //current lcn for any active vc (not the one we are tuned/tuning to) int edacs_tuned_lcn; //the vc we are currently tuned to...above variable is for updating all in the matrix int edacs_vc_call_type; //the type of call on the given VC - see defines below + int edacs_a_bits; // Agency Significant Bits + int edacs_f_bits; // Fleet Significant Bits + int edacs_s_bits; //Subfleet Significant Bits + int edacs_a_shift; //Calculated Shift for A Bits + int edacs_f_shift; //Calculated Shift for F Bits + int edacs_a_mask; //Calculated Mask for A Bits + int edacs_f_mask; //Calculated Mask for F Bits + int edacs_s_mask; //Calculated Mask for S Bits //flags for EDACS call type #define EDACS_IS_VOICE 0x01 diff --git a/src/dsd_main.c b/src/dsd_main.c index 0a9c360..01a5d69 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -1070,6 +1070,14 @@ initState (dsd_state * state) state->edacs_cc_lcn = 0; state->edacs_vc_lcn = 0; state->edacs_tuned_lcn = -1; + state->edacs_a_bits = 4; // Agency Significant Bits + state->edacs_f_bits = 4; // Fleet Significant Bits + state->edacs_s_bits = 3; //Subfleet Significant Bits + state->edacs_a_shift = 7; //Calculated Shift for A Bits + state->edacs_f_shift = 3; //Calculated Shift for F Bits + state->edacs_a_mask = 0xF; //Calculated Mask for A Bits + state->edacs_f_mask = 0xF; //Calculated Mask for F Bits + state->edacs_s_mask = 0x7; //Calculated Mask for S Bits //trunking memset (state->trunk_lcn_freq, 0, sizeof(state->trunk_lcn_freq)); @@ -1356,6 +1364,8 @@ usage () printf (" -fp Decode only ProVoice*\n"); printf (" -fh Decode only EDACS Standard/ProVoice*\n"); printf (" -fH Decode only EDACS Standard/ProVoice with ESK 0xA0*\n"); + printf (" -fh344 Decode only EDACS Standard/ProVoice and set AFS to 344 or custom 11-bit scheme*\n"); + printf (" -fH434 Decode only EDACS Standard/ProVoice and set AFS to 344 or custom 11-bit scheme with ESK 0xA0*\n"); printf (" -fe Decode only EDACS EA/ProVoice*\n"); printf (" -fE Decode only EDACS EA/ProVoice with ESK 0xA0*\n"); printf (" -fm Decode only dPMR*\n"); @@ -2225,6 +2235,16 @@ main (int argc, char **argv) } else if (optarg[0] == 'h') //standard / net w/o ESK { + // does it make sense to do it this way? + if (optarg[1] != 0) + { + char abits[2]; abits[0] = optarg[1]; abits[1] = 0; + char fbits[2]; fbits[0] = optarg[2]; fbits[1] = 0; + char sbits[2]; sbits[0] = optarg[3]; sbits[1] = 0; + state.edacs_a_bits = atoi (&abits[0]); + state.edacs_f_bits = atoi (&fbits[0]); + state.edacs_s_bits = atoi (&sbits[0]); + } opts.frame_dstar = 0; opts.frame_x2tdma = 0; opts.frame_p25p1 = 0; @@ -2254,12 +2274,34 @@ main (int argc, char **argv) fprintf (stderr,"Setting symbol rate to 9600 / second\n"); fprintf (stderr,"Decoding EDACS STD/NET and ProVoice frames.\n"); fprintf (stderr,"EDACS Analog Voice Channels are Experimental.\n"); + //sanity check, make sure we tally up to 11 bits, or set to default values + if (optarg[1] != 0) + { + if ( (state.edacs_a_bits + state.edacs_f_bits + state.edacs_s_bits) != 11) + { + fprintf (stderr, "Invalid AFS Configuration: Reverting to Default.\n"); + state.edacs_a_bits = 4; + state.edacs_f_bits = 4; + state.edacs_s_bits = 3; + } + fprintf (stderr, "AFS Setup in %d:%d:%d configuration.\n", state.edacs_a_bits, state.edacs_f_bits, state.edacs_s_bits); + } //rtl specific tweaks opts.rtl_bandwidth = 24; // opts.rtl_gain_value = 36; } else if (optarg[0] == 'H') //standard / net w/ ESK { + // does it make sense to do it this way? + if (optarg[1] != 0) + { + char abits[2]; abits[0] = optarg[1]; abits[1] = 0; + char fbits[2]; fbits[0] = optarg[2]; fbits[1] = 0; + char sbits[2]; sbits[0] = optarg[3]; sbits[1] = 0; + state.edacs_a_bits = atoi (&abits[0]); + state.edacs_f_bits = atoi (&fbits[0]); + state.edacs_s_bits = atoi (&sbits[0]); + } opts.frame_dstar = 0; opts.frame_x2tdma = 0; opts.frame_p25p1 = 0; @@ -2289,6 +2331,18 @@ main (int argc, char **argv) fprintf (stderr,"Setting symbol rate to 9600 / second\n"); fprintf (stderr,"Decoding EDACS STD/NET w/ ESK and ProVoice frames.\n"); fprintf (stderr,"EDACS Analog Voice Channels are Experimental.\n"); + //sanity check, make sure we tally up to 11 bits, or set to default values + if (optarg[1] != 0) + { + if ( (state.edacs_a_bits + state.edacs_f_bits + state.edacs_s_bits) != 11) + { + fprintf (stderr, "Invalid AFS Configuration: Reverting to Default.\n"); + state.edacs_a_bits = 4; + state.edacs_f_bits = 4; + state.edacs_s_bits = 3; + } + fprintf (stderr, "AFS Setup in %d:%d:%d configuration.\n", state.edacs_a_bits, state.edacs_f_bits, state.edacs_s_bits); + } //rtl specific tweaks opts.rtl_bandwidth = 24; // opts.rtl_gain_value = 36; diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index d314f7a..83d9d16 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -3543,10 +3543,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) } for (i = 1; i <= state->edacs_lcn_count; i++) { - // Compute 4:4:3 AFS for display purposes only - int a = (call_matrix[i][2] >> 7) & 0xF; - int f = (call_matrix[i][2] >> 3) & 0xF; - int s = call_matrix[i][2] & 0x7; + // Compute AFS for display purposes only + int a = (call_matrix[i][2] >> state->edacs_a_shift) & state->edacs_a_mask; + int f = (call_matrix[i][2] >> state->edacs_f_shift) & state->edacs_f_mask; + int s = call_matrix[i][2] & state->edacs_s_mask; printw ("| - LCN [%02d][%010.06lf] MHz", i, (double)state->trunk_lcn_freq[i-1]/1000000); //print Control Channel on LCN line with the current Control Channel @@ -3792,10 +3792,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) // Voice call if ((call_matrix[j][4] & EDACS_IS_VOICE) != 0) { - // Compute 4:4:3 AFS for display purposes only - int a = (call_matrix[j][2] >> 7) & 0xF; - int f = (call_matrix[j][2] >> 3) & 0xF; - int s = call_matrix[j][2] & 0x7; + // Compute AFS for display purposes only + int a = (call_matrix[j][2] >> state->edacs_a_shift) & state->edacs_a_mask; + int f = (call_matrix[j][2] >> state->edacs_f_shift) & state->edacs_f_mask; + int s = call_matrix[j][2] & state->edacs_s_mask; // Group call if ((call_matrix[j][4] & EDACS_IS_GROUP) != 0) diff --git a/src/edacs-fme.c b/src/edacs-fme.c index 0b92c1c..0d7d0c4 100644 --- a/src/edacs-fme.c +++ b/src/edacs-fme.c @@ -349,9 +349,9 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn fprintf (stderr, " Analog RMS: %04ld SQL: %ld", rms, sql); if (state->ea_mode == 0) { - int a = (afs >> 7) & 0xF; - int f = (afs >> 3) & 0xF; - int s = afs & 0x7; + int a = (afs >> state->edacs_a_shift) & state->edacs_a_mask; + int f = (afs >> state->edacs_f_shift) & state->edacs_f_mask; + int s = afs & state->edacs_s_mask; fprintf (stderr, " AFS [%03d] [%02d-%02d%01d] LCN [%02d]", afs, a, f, s, lcn); } else @@ -430,14 +430,51 @@ void edacs(dsd_opts * opts, dsd_state * state) unsigned long long int fr_1t = 0xFFFFFFFFFF; //40 bit return from BCH with poly attached unsigned long long int fr_4m = 0xFFFFFFF; //28-bit 7X message portion to pass to bch handler unsigned long long int fr_4t = 0xFFFFFFFFFF; //40 bit return from BCH with poly attached + + //calculate afs shifts and masks (if user cycles them around) - //commands; may not use these anymore - unsigned int vcmd = 0xEE; //voice command variable - unsigned int idcmd = 0xFD; - unsigned int peercmd = 0xF88; //using for EA detection test - unsigned int netcmd = 0xF3; //using for Networked Test - UNUSED2(vcmd, idcmd); - UNUSED2(peercmd, netcmd); + //quick sanity check, if bit tallies are not 11, reset to default 4:4:3 configuration + if ( (state->edacs_a_bits + state->edacs_f_bits + state->edacs_s_bits) != 11) + { + state->edacs_a_bits = 4; + state->edacs_f_bits = 4; + state->edacs_s_bits = 3; + } + + //calculate shifts by totalling preceeding bits + state->edacs_a_shift = state->edacs_f_bits + state->edacs_s_bits; + state->edacs_f_shift = state->edacs_s_bits; + + //calculate masks via overkill copy and paste + if (state->edacs_a_bits == 1) state->edacs_a_mask = 0x1; + if (state->edacs_a_bits == 2) state->edacs_a_mask = 0x3; + if (state->edacs_a_bits == 3) state->edacs_a_mask = 0x7; + if (state->edacs_a_bits == 4) state->edacs_a_mask = 0xF; + if (state->edacs_a_bits == 5) state->edacs_a_mask = 0x1F; + if (state->edacs_a_bits == 6) state->edacs_a_mask = 0x3F; + if (state->edacs_a_bits == 7) state->edacs_a_mask = 0x7F; + if (state->edacs_a_bits == 8) state->edacs_a_mask = 0xFF; + if (state->edacs_a_bits == 9) state->edacs_a_mask = 0x1FF; + + if (state->edacs_f_bits == 1) state->edacs_s_mask = 0x1; + if (state->edacs_f_bits == 2) state->edacs_s_mask = 0x3; + if (state->edacs_f_bits == 3) state->edacs_s_mask = 0x7; + if (state->edacs_f_bits == 4) state->edacs_s_mask = 0xF; + if (state->edacs_f_bits == 5) state->edacs_s_mask = 0x1F; + if (state->edacs_f_bits == 6) state->edacs_s_mask = 0x3F; + if (state->edacs_f_bits == 7) state->edacs_s_mask = 0x7F; + if (state->edacs_f_bits == 8) state->edacs_s_mask = 0xFF; + if (state->edacs_f_bits == 9) state->edacs_s_mask = 0x1FF; + + if (state->edacs_s_bits == 1) state->edacs_s_mask = 0x1; + if (state->edacs_s_bits == 2) state->edacs_s_mask = 0x3; + if (state->edacs_s_bits == 3) state->edacs_s_mask = 0x7; + if (state->edacs_s_bits == 4) state->edacs_s_mask = 0xF; + if (state->edacs_s_bits == 5) state->edacs_s_mask = 0x1F; + if (state->edacs_s_bits == 6) state->edacs_s_mask = 0x3F; + if (state->edacs_s_bits == 7) state->edacs_s_mask = 0x7F; + if (state->edacs_s_bits == 8) state->edacs_s_mask = 0xFF; + if (state->edacs_s_bits == 9) state->edacs_s_mask = 0x1FF; char * timestr; //add timestr here, so we can assign it and also free it to prevent memory leak timestr = getTimeE();