EDACS: Display cached call source on Standard, tune group calls on assignment (#241)
* Trim trailing whitespace * EDACS: Display cached call source on Standard The logic in `edacs-fme.c` didn't work, in retrospect, because it would have depended on getting back-to-back messages for the same call. In practice, that is unlikely even on an idle system as system state gets displayed. Instead, cache on the display end, for a "better" user experience. * EDACS: Pad channel freq to "000.000000 MHz" * EDACS: Process/tune group calls on assignment
This commit is contained in:
parent
8d432e8b3e
commit
c8d00846b1
|
|
@ -210,8 +210,8 @@ typedef struct
|
|||
SF_INFO *audio_in_file_info;
|
||||
|
||||
uint32_t rtlsdr_center_freq;
|
||||
int rtlsdr_ppm_error;
|
||||
int audio_in_type;
|
||||
int rtlsdr_ppm_error;
|
||||
int audio_in_type;
|
||||
char audio_out_dev[1024];
|
||||
int audio_out_fd;
|
||||
int audio_out_fdR; //right channel audio for OSS hack
|
||||
|
|
@ -367,7 +367,7 @@ typedef struct
|
|||
char group_in_file[1024];
|
||||
char lcn_in_file[1024];
|
||||
char chan_in_file[1024];
|
||||
char key_in_file[1024];
|
||||
char key_in_file[1024];
|
||||
//end import filenames
|
||||
|
||||
//reverse mute
|
||||
|
|
@ -454,7 +454,7 @@ typedef struct
|
|||
short s_ru[160*6]; //single sample right
|
||||
short s_l4u[4][160*6]; //quad sample for up to a P25p2 4V
|
||||
short s_r4u[4][160*6]; //quad sample for up to a P25p2 4V
|
||||
//end
|
||||
//end
|
||||
int audio_out_idx;
|
||||
int audio_out_idx2;
|
||||
int audio_out_idxR;
|
||||
|
|
@ -616,7 +616,7 @@ typedef struct
|
|||
|
||||
char dmr_cach_fragment[4][17]; //unsure of size, will need to check/verify
|
||||
int dmr_cach_counter; //counter for dmr_cach_fragments 0-3; not sure if needed yet.
|
||||
|
||||
|
||||
//dmr talker alias new/fixed stuff
|
||||
uint8_t dmr_alias_format[2]; //per slot
|
||||
uint8_t dmr_alias_len[2]; //per slot
|
||||
|
|
@ -1188,7 +1188,7 @@ bool crc8_ok(uint8_t bits[], unsigned int len);
|
|||
//modified CRC functions for SB/RC
|
||||
uint8_t crc7(uint8_t bits[], unsigned int len);
|
||||
uint8_t crc3(uint8_t bits[], unsigned int len);
|
||||
uint8_t crc4(uint8_t bits[], unsigned int len);
|
||||
uint8_t crc4(uint8_t bits[], unsigned int len);
|
||||
|
||||
//LFSR and LFSRP code courtesy of https://github.com/mattames/LFSR/
|
||||
void LFSR(dsd_state * state);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
*
|
||||
* LWVMOBILE
|
||||
* 2022-08 DSD-FME Florida Man Edition
|
||||
*
|
||||
* ilyacodes
|
||||
* 2024-03 EDACS-FME display improvements
|
||||
*-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
|
@ -110,13 +113,13 @@ char * DMRBusrtTypes[32] = {
|
|||
"R34D ",
|
||||
"IDLE ",
|
||||
"R1_D ",
|
||||
"ERR ",
|
||||
"ERR ",
|
||||
"DUID ERR ",
|
||||
"R-S ERR ",
|
||||
"CRC ERR ",
|
||||
"NULL ",
|
||||
"VOICE",
|
||||
" ",
|
||||
"VOICE",
|
||||
" ",
|
||||
"INIT ",
|
||||
"INIT ",
|
||||
"PTT", //20 MAC
|
||||
|
|
@ -188,7 +191,7 @@ void beeper (dsd_opts * opts, dsd_state * state, int lr)
|
|||
|
||||
if (opts->pulse_digi_out_channels == 1 && opts->floating_point == 0)
|
||||
pa_simple_write(opts->pulse_digi_dev_out, samp_s, 160*2, NULL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
else if (opts->audio_out_type == 8) //UDP Audio
|
||||
|
|
@ -204,7 +207,7 @@ void beeper (dsd_opts * opts, dsd_state * state, int lr)
|
|||
|
||||
if (opts->pulse_digi_out_channels == 1 && opts->floating_point == 0)
|
||||
udp_socket_blaster (opts, state, 160*2, samp_s);
|
||||
|
||||
|
||||
}
|
||||
|
||||
else if (opts->audio_out_type == 1) //STDOUT
|
||||
|
|
@ -245,10 +248,10 @@ void beeper (dsd_opts * opts, dsd_state * state, int lr)
|
|||
samp_su[(i*6)+4] = outbuf[4];
|
||||
samp_su[(i*6)+5] = outbuf[5];
|
||||
}
|
||||
|
||||
|
||||
write (opts->audio_out_fd, samp_su, 960*2);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -328,7 +331,7 @@ char *choicesc[] = {
|
|||
"Setup and Start RTL Input ",
|
||||
"Retune RTL Dongle ",
|
||||
"Toggle C4FM/QPSK (P2 TDMA CC)",
|
||||
"Toggle C4FM/QPSK (P1 FDMA CC)",
|
||||
"Toggle C4FM/QPSK (P1 FDMA CC)",
|
||||
"Start TCP Direct Link Audio",
|
||||
"Configure RIGCTL",
|
||||
"Stop All Decoded WAV Saving",
|
||||
|
|
@ -415,7 +418,7 @@ void ncursesOpen (dsd_opts * opts, dsd_state * state)
|
|||
//this is primarily used to push a quick audio blip through OSS so it will show up in the mixer immediately
|
||||
// if (opts->audio_out_type == 2 || opts->audio_out_type == 5)
|
||||
// beeper (opts, state, 0); //causes crash in Cygwin when mixed input/output
|
||||
|
||||
|
||||
//terminate all values
|
||||
for (int i = 0; i < 10; i++)
|
||||
sprintf (alias_ch[i], "%s", "");
|
||||
|
|
@ -462,7 +465,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
|
|||
closePulseOutput (opts);
|
||||
}
|
||||
|
||||
//close OSS output
|
||||
//close OSS output
|
||||
if (opts->audio_out_type == 2 || opts->audio_out_type == 5)
|
||||
{
|
||||
close (opts->audio_out_fd);
|
||||
|
|
@ -760,7 +763,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
|
|||
opts->rtl_dev_index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
entry_win = newwin(17, WIDTH+20, starty+10, startx+10);
|
||||
|
|
@ -861,7 +864,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
|
|||
// if (opts->audio_out == 0)
|
||||
// {
|
||||
// opts->audio_out = 1;
|
||||
// opts->audio_out_type = 0;
|
||||
// opts->audio_out_type = 0;
|
||||
// // state->audio_out_buf_p = 0;
|
||||
// // state->audio_out_buf_pR = 0;
|
||||
// state->audio_out_idx = 0;
|
||||
|
|
@ -933,7 +936,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
|
|||
opts->audio_in_type = 0;
|
||||
}
|
||||
else opts->audio_in_type = 5;
|
||||
|
||||
|
||||
}
|
||||
|
||||
state->audio_smoothing = 0; //disable smoothing to prevent random crackling/buzzing
|
||||
|
|
@ -1222,7 +1225,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
|
|||
wscanw(entry_win, "%lld", &state->R);
|
||||
noecho();
|
||||
if (state->R > 0x7FFF) state->R = 0x7FFF;
|
||||
|
||||
|
||||
state->keyloader = 0; //turn off keyloader
|
||||
}
|
||||
//toggle enforcement of basic privacy key over enc bit set on traffic
|
||||
|
|
@ -1844,7 +1847,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
|
|||
{
|
||||
openOSSOutput (opts);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (opts->audio_in_type == 0) //reopen pulse input if it is the specified input method
|
||||
{
|
||||
|
|
@ -1854,7 +1857,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
|
|||
if (opts->audio_in_type == 3) //open rtl input if it is the specified input method
|
||||
{
|
||||
// ncursesPrinter (opts, state); //not sure why this was placed here originally, but causes a double free core dump when calling free(timestr)
|
||||
#ifdef USE_RTLSDR
|
||||
#ifdef USE_RTLSDR
|
||||
if (opts->rtl_started == 0)
|
||||
{
|
||||
opts->rtl_started = 1; //set here so ncurses terminal doesn't attempt to open it again
|
||||
|
|
@ -1892,7 +1895,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
|
||||
if (opts->audio_in_type != 1) //can't run getch/menu when using STDIN -
|
||||
{
|
||||
timeout(0); //
|
||||
timeout(0); //
|
||||
c = getch(); //
|
||||
}
|
||||
|
||||
|
|
@ -1908,7 +1911,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
//Variable reset/set section
|
||||
|
||||
//set lls sync types
|
||||
if (state->synctype >= 0 && state->synctype < 39)
|
||||
if (state->synctype >= 0 && state->synctype < 39)
|
||||
{
|
||||
lls = state->synctype;
|
||||
}
|
||||
|
|
@ -2002,16 +2005,22 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
//Edacs - ProVoice
|
||||
if ( (lls == 14 || lls == 15 || lls == 37 || lls == 38) && state->carrier == 1)
|
||||
{
|
||||
|
||||
if (state->edacs_vc_lcn != -1)
|
||||
|
||||
if (state->edacs_vc_lcn != -1)
|
||||
{
|
||||
call_matrix[state->edacs_vc_lcn][0] = lls;
|
||||
call_matrix[state->edacs_vc_lcn][1] = state->edacs_vc_lcn;
|
||||
call_matrix[state->edacs_vc_lcn][2] = state->lasttg;
|
||||
call_matrix[state->edacs_vc_lcn][3] = state->lastsrc;
|
||||
call_matrix[state->edacs_vc_lcn][2] = state->lasttg;
|
||||
//EDACS standard does not provide source LIDs on channel update messages; instead, for the sake of display, let's
|
||||
//assume the prior source for a given LCN is still accurate, unless we have an updated one provided.
|
||||
//
|
||||
//If you MUST have perfectly-accurate source LIDs, look at the logged CC messages yourself - incorrect source LIDs
|
||||
//may be displayed if we miss an initial call channel assignment.
|
||||
if (state->ea_mode == 1 || state->lastsrc != 0)
|
||||
call_matrix[state->edacs_vc_lcn][3] = state->lastsrc;
|
||||
call_matrix[state->edacs_vc_lcn][4] = 1;
|
||||
call_matrix[state->edacs_vc_lcn][5] = time(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -2074,7 +2083,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//TODO: Find better placement for these
|
||||
if ( strcmp(state->str50a, "") != 0 )
|
||||
sprintf (alias_ch[9], "%s", state->str50a);
|
||||
|
|
@ -2257,7 +2266,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
// state->lastsrc = 0;
|
||||
// rd = 0;
|
||||
// tg = 0;
|
||||
// }
|
||||
// }
|
||||
// if (state->dmrburstR == 2 && state->dmr_end_alert[1] == 0) //if TLC and flag not tripped
|
||||
// {
|
||||
// beeper (opts, state, 1);
|
||||
|
|
@ -2266,7 +2275,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
// state->lastsrcR = 0;
|
||||
// rdR = 0;
|
||||
// tgR = 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
//Start Printing Section
|
||||
|
|
@ -2276,7 +2285,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
{
|
||||
printw ("------------------------------------------------------------------------------\n");
|
||||
printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "AW (20231015)");
|
||||
printw ("------------------------------------------------------------------------------\n");
|
||||
printw ("------------------------------------------------------------------------------\n");
|
||||
}
|
||||
#elif LIMAZULUTWEAKS
|
||||
if (opts->ncurses_compact == 1)
|
||||
|
|
@ -2318,7 +2327,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
#elif ZDEV_BUILD
|
||||
if (i == 5) printw (" %s ", "AW ");
|
||||
if (i == 6) printw (" %s \n", GIT_TAG);
|
||||
#else
|
||||
#else
|
||||
if (i == 5) printw (" %s ", "AW ");
|
||||
if (i == 6) printw (" %s \n", GIT_TAG);
|
||||
#endif
|
||||
|
|
@ -2383,7 +2392,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
printw (" SQ: %i;", opts->rtl_squelch_level);
|
||||
printw (" RMS: %04li;", opts->rtl_rms);
|
||||
printw (" BW: %i kHz;", opts->rtl_bandwidth);
|
||||
printw (" FRQ: %i;", opts->rtlsdr_center_freq);
|
||||
printw (" FRQ: %i;", opts->rtlsdr_center_freq);
|
||||
if (opts->rtl_udp_port != 0) printw ("\n| External RTL Tuning on UDP Port: %i", opts->rtl_udp_port);
|
||||
printw ("\n");
|
||||
}
|
||||
|
|
@ -2529,7 +2538,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
attron(COLOR_PAIR(2));
|
||||
printw (" Standard/Network");
|
||||
attron(COLOR_PAIR(4));
|
||||
printw (" Extended Address");
|
||||
printw (" Extended Address");
|
||||
}
|
||||
printw (" Mode (S);");
|
||||
|
||||
|
|
@ -2556,7 +2565,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
else if (state->ea_mode == 1)
|
||||
{
|
||||
printw (" standard/network");
|
||||
printw (" EXTENDED ADDRESS");
|
||||
printw (" EXTENDED ADDRESS");
|
||||
}
|
||||
printw (" Mode (S);");
|
||||
|
||||
|
|
@ -2581,9 +2590,9 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
if (opts->scanner_mode == 1)
|
||||
{
|
||||
printw ("| Scan Mode: ");
|
||||
if (state->lcn_freq_roll != 0)
|
||||
if (state->lcn_freq_roll != 0)
|
||||
printw (" Frequency: %.06lf Mhz", (double)state->trunk_lcn_freq[state->lcn_freq_roll-1]/1000000);
|
||||
printw (" Speed: %.02lf sec \n", opts->trunk_hangtime); //not sure values less than 1 make a difference, may be system/environment dependent
|
||||
printw (" Speed: %.02lf sec \n", opts->trunk_hangtime); //not sure values less than 1 make a difference, may be system/environment dependent
|
||||
}
|
||||
|
||||
if (opts->reverse_mute == 1) printw ("| Reverse Mute - Muting Unencrypted Voice\n");
|
||||
|
|
@ -2625,7 +2634,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
}
|
||||
printw ("\n");
|
||||
printw ("| In Level: [%02d%%] \n", level);
|
||||
|
||||
|
||||
if (opts->dmr_stereo == 0)
|
||||
{
|
||||
printw ("| Voice Error: [%i][%i]", state->errs, state->errs2);
|
||||
|
|
@ -2648,7 +2657,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
printw ("------------------------------------------------------------------------------\n");
|
||||
|
||||
printw ("--Call Info-------------------------------------------------------------------\n");
|
||||
|
||||
|
||||
//DSTAR
|
||||
if (lls == 6 || lls == 7 || lls == 18 || lls == 19)
|
||||
{
|
||||
|
|
@ -2689,7 +2698,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
printw("RESERVED (%012llx) ", state->m17_dst);
|
||||
else
|
||||
printw("%s", state->m17_dst_str);
|
||||
|
||||
|
||||
printw ("\n");
|
||||
printw ("| ");
|
||||
|
||||
|
|
@ -2699,7 +2708,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
else
|
||||
printw("%s", state->m17_src_str);
|
||||
|
||||
|
||||
|
||||
printw ("\n");
|
||||
printw ("| ");
|
||||
|
||||
|
|
@ -2726,7 +2735,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
if (state->m17_enc == 3)
|
||||
{
|
||||
printw (" Reserved Enc - Type: %d", state->m17_enc_st);
|
||||
}
|
||||
}
|
||||
|
||||
printw ("\n");
|
||||
|
||||
|
|
@ -2787,7 +2796,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
// printw ("%c", state->ysf_txt[i][j]);
|
||||
// }
|
||||
// // printw (" "); //just a single space between each 'block'
|
||||
// }
|
||||
// }
|
||||
|
||||
printw ("\n");
|
||||
|
||||
|
|
@ -2810,7 +2819,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
{
|
||||
printw (" - Frequency: %.06lf Mhz ", (double)state->p25_cc_freq/1000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (opts->p25_is_tuned == 1)
|
||||
{
|
||||
if (idas == 0) printw ("Monitoring RTCH Channel"); //Traffic Channel
|
||||
|
|
@ -2823,8 +2832,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
|
||||
printw ("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
printw ("| ");
|
||||
// #ifdef LIMAZULUTWEAKS
|
||||
|
|
@ -2922,10 +2931,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
}
|
||||
|
||||
//Active Trunking Channels (NXDN and IDAS)
|
||||
if (1 == 1) //opts->p25_trunk
|
||||
if (1 == 1) //opts->p25_trunk
|
||||
{
|
||||
printw ("\n");
|
||||
printw ("| ");
|
||||
printw ("| ");
|
||||
|
||||
//active channel display
|
||||
attron(COLOR_PAIR(4));
|
||||
|
|
@ -2943,8 +2952,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
|
||||
printw("\n");
|
||||
}
|
||||
|
||||
//P25 and DMR BS/MS
|
||||
|
||||
//P25 and DMR BS/MS
|
||||
if ( lls == 0 || lls == 1 || lls == 12 || lls == 13 || lls == 10 ||
|
||||
lls == 11 || lls == 32 || lls == 33 || lls == 34 || lls == 35 || lls == 36)
|
||||
{
|
||||
|
|
@ -2955,7 +2964,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
// printw ("%s %s", state->dmr_branding, state->dmr_branding_sub);
|
||||
printw ("%s ", state->dmr_branding);
|
||||
printw ("%s", state->dmr_branding_sub);
|
||||
printw ("%s", state->dmr_site_parms); //site id, net id, etc
|
||||
printw ("%s", state->dmr_site_parms); //site id, net id, etc
|
||||
if (state->dmr_rest_channel > 0)
|
||||
{
|
||||
printw ("Rest LSN: %02d; ", state->dmr_rest_channel);
|
||||
|
|
@ -2968,7 +2977,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
{
|
||||
printw ("Freq: %.06lf MHz", (double)state->p25_cc_freq/1000000);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (lls == 32 || lls == 33 || lls == 34)
|
||||
{
|
||||
|
|
@ -2997,7 +3006,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
printw (" Phase 2 Invalid Parameters ");
|
||||
attron(COLOR_PAIR(3));
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if (state->p25_cc_freq != 0)
|
||||
{
|
||||
|
|
@ -3119,7 +3128,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
|
||||
//Not always correct, or correct at all, depends on context
|
||||
//this is already in the call_string anyways
|
||||
|
||||
|
||||
// if(state->dmrburstL == 16 && state->dmr_so == 0x40 && state->R == 0) //0100 0000
|
||||
// {
|
||||
// attron(COLOR_PAIR(2));
|
||||
|
|
@ -3156,13 +3165,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
|
||||
//Embedded GPS (not LRRP)
|
||||
printw ("%s ", state->dmr_embedded_gps[0]);
|
||||
|
||||
|
||||
//Embedded Talker Alias Blocks
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < 7; j++)
|
||||
{
|
||||
printw ("%s", state->dmr_alias_block_segment[0][i][j]);
|
||||
printw ("%s", state->dmr_alias_block_segment[0][i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3205,7 +3214,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
|
||||
//Slot 2 [1] -- Also Including DMR MS now to keep the display more 'uniform' in nature
|
||||
// if (lls < 30 || lls == 35 || lls == 36)
|
||||
{
|
||||
{
|
||||
printw ("| SLOT 2 - ");
|
||||
if (state->dmrburstR < 16 && state->carrier == 1 && state->lasttgR > 0 && state->lastsrcR > 0)
|
||||
{
|
||||
|
|
@ -3221,10 +3230,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
printw ("%s | ", state->call_string[1]);
|
||||
printw ("%s ", DMRBusrtTypes[state->dmrburstR]);
|
||||
|
||||
if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21) ) printw ("*M*");
|
||||
if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21) ) printw ("*M*");
|
||||
|
||||
printw ("\n");
|
||||
|
||||
|
||||
printw ("| V XTRA | "); //10 spaces
|
||||
|
||||
if(state->dmrburstR == 16 && state->payload_algidR == 0 && (state->dmr_soR & 0xCF) == 0x40) //4F or CF mask?
|
||||
|
|
@ -3345,7 +3354,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
|
||||
if(state->dmrburstR == 16 || state->dmrburstR == 21) //only during call
|
||||
{
|
||||
|
||||
|
||||
//Embedded GPS (not LRRP)
|
||||
attron(COLOR_PAIR(4));
|
||||
printw ("%s ", state->dmr_embedded_gps[1]);
|
||||
|
|
@ -3355,7 +3364,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
{
|
||||
for (int j = 0; j < 7; j++)
|
||||
{
|
||||
printw ("%s", state->dmr_alias_block_segment[1][i][j]);
|
||||
printw ("%s", state->dmr_alias_block_segment[1][i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3373,7 +3382,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
attron(COLOR_PAIR(4));
|
||||
printw ("%s", state->dmr_lrrp_gps[1]);
|
||||
}
|
||||
|
||||
|
||||
//Group Name Labels from CSV import
|
||||
if (state->dmrburstR == 16 || state->dmrburstR > 19)
|
||||
{
|
||||
|
|
@ -3461,7 +3470,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
//EDACS and ProVoice
|
||||
if (lls == 14 || lls == 15 || lls == 37 || lls == 38)
|
||||
{
|
||||
attroff (COLOR_PAIR(3)); //colors off for EDACS
|
||||
attroff (COLOR_PAIR(3)); //colors off for EDACS
|
||||
if (state->edacs_site_id != 0)
|
||||
{
|
||||
if (opts->p25_is_tuned == 0)
|
||||
|
|
@ -3472,8 +3481,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
{
|
||||
printw ("| Monitoring Voice Channel - LCN [%02d]\n", state->edacs_tuned_lcn);
|
||||
//since we are tuned, keep updating the time so it doesn't disappear during call
|
||||
call_matrix[state->edacs_tuned_lcn][5] = time(NULL);
|
||||
}
|
||||
call_matrix[state->edacs_tuned_lcn][5] = time(NULL);
|
||||
}
|
||||
printw ("| SITE [%03lld][%02llX]", state->edacs_site_id, state->edacs_site_id);
|
||||
|
||||
if (state->ea_mode == 1)
|
||||
|
|
@ -3493,8 +3502,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
// Compute 4:4:3 AFS for display purposes only
|
||||
int a = (call_matrix[i][2] >> 7) & 0xF;
|
||||
int fs = call_matrix[i][2] & 0x7F;
|
||||
printw ("| - LCN [%02d][%.06lf] MHz", i, (double)state->trunk_lcn_freq[i-1]/1000000);
|
||||
|
||||
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
|
||||
if ( (i) == state->edacs_cc_lcn)
|
||||
{
|
||||
|
|
@ -3503,9 +3512,9 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
attroff (COLOR_PAIR(1));
|
||||
}
|
||||
//print active calls on corresponding LCN line
|
||||
if ((i != state->edacs_cc_lcn) && time(NULL) - call_matrix[i][5] < 2)
|
||||
if ((i != state->edacs_cc_lcn) && time(NULL) - call_matrix[i][5] < 2)
|
||||
{
|
||||
attron (COLOR_PAIR(3));
|
||||
attron (COLOR_PAIR(3));
|
||||
if (state->ea_mode == 1) {
|
||||
if (call_matrix[i][2] + 1 == 0)
|
||||
// System all-call
|
||||
|
|
@ -3544,12 +3553,12 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
break;
|
||||
}
|
||||
}
|
||||
attroff (COLOR_PAIR(3));
|
||||
attroff (COLOR_PAIR(3));
|
||||
}
|
||||
//print dying or dead calls in red for x seconds longer
|
||||
if ( (i != state->edacs_cc_lcn) && (time(NULL) - call_matrix[i][5] >= 2) && (time(NULL) - call_matrix[i][5] < 5) )
|
||||
//print dying or dead calls in red for x seconds longer
|
||||
if ( (i != state->edacs_cc_lcn) && (time(NULL) - call_matrix[i][5] >= 2) && (time(NULL) - call_matrix[i][5] < 5) )
|
||||
{
|
||||
attron (COLOR_PAIR(2));
|
||||
attron (COLOR_PAIR(2));
|
||||
if (state->ea_mode == 1) {
|
||||
if (call_matrix[i][2] + 1 == 0)
|
||||
// System all-call
|
||||
|
|
@ -3588,14 +3597,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
break;
|
||||
}
|
||||
}
|
||||
attroff (COLOR_PAIR(2));
|
||||
attroff (COLOR_PAIR(2));
|
||||
}
|
||||
if (i == state->edacs_tuned_lcn && opts->p25_is_tuned == 1) printw (" **T**"); //asterisk which lcn is opened
|
||||
printw ("\n");
|
||||
}
|
||||
if (state->carrier == 1)
|
||||
{
|
||||
attron (COLOR_PAIR(3));
|
||||
attron (COLOR_PAIR(3));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3687,10 +3696,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
//EDACS and ProVoice, outside of timestamp loop
|
||||
if (call_matrix[j][0] == 14 || call_matrix[j][0] == 15 || call_matrix[j][0] == 37 || call_matrix[j][0] == 38 )
|
||||
{
|
||||
if (call_matrix[j][2] != 0)
|
||||
if (call_matrix[j][2] != 0)
|
||||
{
|
||||
printw ("| ");
|
||||
printw ("%s ", getDateC(call_matrix[j][5]) );
|
||||
printw ("%s ", getDateC(call_matrix[j][5]) );
|
||||
printw ("%s ", getTimeC(call_matrix[j][5]) );
|
||||
printw ("LCN [%2lld] ", call_matrix[j][1]);
|
||||
if (state->ea_mode == 1)
|
||||
|
|
@ -3705,10 +3714,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
// Group call
|
||||
printw ("Target [%8lld] Source [%8lld]", call_matrix[j][2], call_matrix[j][3]);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
// Compute 4:4:3 AFS for display purposes only
|
||||
int a = (call_matrix[j][2] >> 7) & 0xF;
|
||||
int a = (call_matrix[j][2] >> 7) & 0xF;
|
||||
int fs = call_matrix[j][2] & 0x7F;
|
||||
if (call_matrix[j][2] + 1 == 0)
|
||||
// System all-call
|
||||
|
|
@ -3719,7 +3728,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
else
|
||||
// Group call
|
||||
printw ("Target [%6lld][%02d-%03d] Source [%5lld]", call_matrix[j][2], a, fs, call_matrix[j][3]);
|
||||
}
|
||||
}
|
||||
//test
|
||||
for (int k = 0; k < state->group_tally; k++)
|
||||
{
|
||||
|
|
@ -3739,7 +3748,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
//end test
|
||||
printw ("\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} //end Call History
|
||||
//fence bottom
|
||||
|
|
@ -3796,7 +3805,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
else if (opts->slot1_on == 0)
|
||||
{
|
||||
opts->slot1_on = 1;
|
||||
if (opts->audio_out_type == 5) //OSS 48k/1
|
||||
if (opts->audio_out_type == 5) //OSS 48k/1
|
||||
{
|
||||
opts->slot_preference = 0; //slot 1
|
||||
// opts->slot2_on = 0; //turn off slot 2
|
||||
|
|
@ -3822,7 +3831,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
else if (opts->slot2_on == 0)
|
||||
{
|
||||
opts->slot2_on = 1;
|
||||
if (opts->audio_out_type == 5) //OSS 48k/1
|
||||
if (opts->audio_out_type == 5) //OSS 48k/1
|
||||
{
|
||||
opts->slot_preference = 1; //slot 2
|
||||
// opts->slot1_on = 0; //turn off slot 1
|
||||
|
|
@ -4028,14 +4037,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
{
|
||||
fprintf (stderr, "-T %s wav file directory does not exist\n", wav_file_directory);
|
||||
fprintf (stderr, "Creating directory %s to save decoded wav files\n", wav_file_directory);
|
||||
mkdir(wav_file_directory, 0700);
|
||||
mkdir(wav_file_directory, 0700);
|
||||
}
|
||||
opts->dmr_stereo_wav = 1;
|
||||
//catch all in case of no file name set, won't crash or something
|
||||
sprintf (opts->wav_out_file, "./%s/DSD-FME-T1.wav", opts->wav_out_dir);
|
||||
sprintf (opts->wav_out_fileR, "./%s/DSD-FME-T2.wav", opts->wav_out_dir);
|
||||
openWavOutFileL (opts, state);
|
||||
openWavOutFileR (opts, state);
|
||||
openWavOutFileL (opts, state);
|
||||
openWavOutFileR (opts, state);
|
||||
}
|
||||
|
||||
//this one could cause issues, but seems okay
|
||||
|
|
@ -4052,15 +4061,15 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
|
||||
//
|
||||
#ifdef AERO_BUILD //this might be okay on Aero as well, will need to look into and/or test
|
||||
//
|
||||
//
|
||||
#else
|
||||
if (c == 115) //'s' key, stop playing wav or symbol in files
|
||||
{
|
||||
if (opts->symbolfile != NULL)
|
||||
{
|
||||
if (opts->audio_in_type == 4)
|
||||
if (opts->audio_in_type == 4)
|
||||
{
|
||||
fclose(opts->symbolfile);
|
||||
fclose(opts->symbolfile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4074,12 +4083,12 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
opts->audio_in_type = 0;
|
||||
openPulseInput(opts);
|
||||
}
|
||||
else opts->audio_in_type = 5; //exitflag = 1;
|
||||
|
||||
else opts->audio_in_type = 5; //exitflag = 1;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
//makes buzzing sound when locked out in new audio config and short, probably something to do with processaudio running or not running
|
||||
|
||||
//makes buzzing sound when locked out in new audio config and short, probably something to do with processaudio running or not running
|
||||
if (state->lasttg != 0 && opts->frame_provoice != 1 && c == 33) //SHIFT+'1' key (exclamation point), lockout slot 1 or conventional tg from tuning/playback during session
|
||||
{
|
||||
state->group_array[state->group_tally].groupNumber = state->lasttg;
|
||||
|
|
@ -4215,40 +4224,40 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
// if (c == 48) //'0' key, toggle upsampled audio smoothing
|
||||
// {
|
||||
// if (state->audio_smoothing == 1) state->audio_smoothing = 0;
|
||||
// else state->audio_smoothing = 1;
|
||||
// else state->audio_smoothing = 1;
|
||||
// }
|
||||
|
||||
if (opts->p25_trunk == 1 && c == 119) //'w' key, toggle white list/black list mode
|
||||
if (opts->p25_trunk == 1 && c == 119) //'w' key, toggle white list/black list mode
|
||||
{
|
||||
if (opts->trunk_use_allow_list == 1) opts->trunk_use_allow_list = 0;
|
||||
else opts->trunk_use_allow_list = 1;
|
||||
else opts->trunk_use_allow_list = 1;
|
||||
}
|
||||
|
||||
if (opts->p25_trunk == 1 && c == 117) //'u' key, toggle tune private calls
|
||||
{
|
||||
if (opts->trunk_tune_private_calls == 1) opts->trunk_tune_private_calls = 0;
|
||||
else opts->trunk_tune_private_calls = 1;
|
||||
else opts->trunk_tune_private_calls = 1;
|
||||
}
|
||||
|
||||
if (opts->p25_trunk == 1 && c == 100) //'d' key, toggle tune data calls
|
||||
{
|
||||
if (opts->trunk_tune_data_calls == 1) opts->trunk_tune_data_calls = 0;
|
||||
else opts->trunk_tune_data_calls = 1;
|
||||
else opts->trunk_tune_data_calls = 1;
|
||||
}
|
||||
|
||||
if (opts->p25_trunk == 1 && c == 101) //'e' key, toggle tune enc calls (P25 only on certain grants)
|
||||
{
|
||||
if (opts->trunk_tune_enc_calls == 1) opts->trunk_tune_enc_calls = 0;
|
||||
else opts->trunk_tune_enc_calls = 1;
|
||||
else opts->trunk_tune_enc_calls = 1;
|
||||
}
|
||||
|
||||
if (opts->p25_trunk == 1 && c == 103) //'g' key, toggle tune group calls
|
||||
{
|
||||
if (opts->trunk_tune_group_calls == 1) opts->trunk_tune_group_calls = 0;
|
||||
else opts->trunk_tune_group_calls = 1;
|
||||
else opts->trunk_tune_group_calls = 1;
|
||||
}
|
||||
|
||||
if (c == 70) //'F' key - toggle agressive sync/crc failure/ras
|
||||
if (c == 70) //'F' key - toggle agressive sync/crc failure/ras
|
||||
{
|
||||
if (opts->aggressive_framesync == 0) opts->aggressive_framesync = 1;
|
||||
else opts->aggressive_framesync = 0;
|
||||
|
|
@ -4256,7 +4265,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
|
||||
if (c == 68) //'D' key - Reset DMR Site Parms/Call Strings, etc.
|
||||
{
|
||||
//dmr trunking/ncurses stuff
|
||||
//dmr trunking/ncurses stuff
|
||||
state->dmr_rest_channel = -1; //init on -1
|
||||
state->dmr_mfid = -1; //
|
||||
|
||||
|
|
@ -4318,7 +4327,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
if (opts->audio_in_type == 0) closePulseInput(opts);
|
||||
fprintf (stderr, "TCP Socket Connected Successfully.\n");
|
||||
opts->audio_in_type = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
else fprintf (stderr, "TCP Socket Connection Error.\n");
|
||||
}
|
||||
|
|
@ -4390,7 +4399,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
state->symbolCenter = 3;
|
||||
}
|
||||
|
||||
fprintf (stderr, "\n User Activated Return to CC; \n ");
|
||||
fprintf (stderr, "\n User Activated Return to CC; \n ");
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -4436,15 +4445,15 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
{
|
||||
state->lcn_freq_roll++;
|
||||
//check roll again if greater than expected, then go back to zero
|
||||
if (state->lcn_freq_roll >= state->lcn_freq_count)
|
||||
if (state->lcn_freq_roll >= state->lcn_freq_count)
|
||||
{
|
||||
state->lcn_freq_roll = 0; //reset to zero
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//check that we have a non zero value first, then tune next frequency
|
||||
if (state->trunk_lcn_freq[state->lcn_freq_roll] != 0)
|
||||
if (state->trunk_lcn_freq[state->lcn_freq_roll] != 0)
|
||||
{
|
||||
//rigctl
|
||||
if (opts->use_rigctl == 1)
|
||||
|
|
@ -4461,7 +4470,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
}
|
||||
|
||||
fprintf (stderr, "\n User Activated Channel Cycle;");
|
||||
fprintf (stderr, " Tuning to Frequency: %.06lf MHz\n",
|
||||
fprintf (stderr, " Tuning to Frequency: %.06lf MHz\n",
|
||||
(double)state->trunk_lcn_freq[state->lcn_freq_roll]/1000000);
|
||||
|
||||
}
|
||||
|
|
@ -4483,18 +4492,18 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
{
|
||||
state->samplesPerSymbol = 8;
|
||||
state->symbolCenter = 3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (opts->m17encoder == 1 && c == 92) //'\' key - toggle M17 encoder Encode + TX
|
||||
if (opts->m17encoder == 1 && c == 92) //'\' key - toggle M17 encoder Encode + TX
|
||||
{
|
||||
if (state->m17encoder_tx == 0) state->m17encoder_tx = 1;
|
||||
else state->m17encoder_tx = 0;
|
||||
|
||||
//flag on the EOT marker to send last frame after toggling encoder to zero
|
||||
if (state->m17encoder_tx == 0) state->m17encoder_eot = 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(opts->frame_provoice == 1 && c == 65) //'A' Key, toggle ESK mask 0xA0
|
||||
|
|
@ -4523,7 +4532,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
}
|
||||
|
||||
//anything with an entry box will need the inputs and outputs stopped first
|
||||
//so probably just write a function to handle c input, and when c = certain values
|
||||
//so probably just write a function to handle c input, and when c = certain values
|
||||
//needing an entry box, then stop all of those
|
||||
|
||||
//allocated memory pointer needs to be free'd each time
|
||||
|
|
|
|||
187
src/edacs-fme.c
187
src/edacs-fme.c
|
|
@ -1,5 +1,5 @@
|
|||
/*-------------------------------------------------------------------------------
|
||||
* EDACS-FME
|
||||
* EDACS-FME
|
||||
* A program for decoding EDACS (ported to DSD-FME)
|
||||
* https://github.com/lwvmobile/edacs-fm
|
||||
*
|
||||
|
|
@ -15,9 +15,9 @@
|
|||
*
|
||||
* LWVMOBILE
|
||||
* 2023-11 Version EDACS-FM Florida Man Edition
|
||||
*
|
||||
*
|
||||
* ilyacodes
|
||||
* 2024-03 added EA i-call and login message decoding
|
||||
* 2024-03 rewrite EDACS standard parsing to spec, add reverse-engineered EA messages
|
||||
*-----------------------------------------------------------------------------*/
|
||||
#include "dsd.h"
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ void openWavOutFile48k (dsd_opts * opts, dsd_state * state)
|
|||
//generic rms type function
|
||||
long int gen_rms(short *samples, int len, int step)
|
||||
{
|
||||
|
||||
|
||||
int i;
|
||||
long int rms;
|
||||
long p, t, s;
|
||||
|
|
@ -184,7 +184,7 @@ void analog_dc_block_filter(short * input, int len)
|
|||
avg = sum / len;
|
||||
avg = (avg + dc_avg * 9) / 10;
|
||||
for (i=0; i < len; i++)
|
||||
input[i] -= (short)avg;
|
||||
input[i] -= (short)avg;
|
||||
|
||||
dc_avg = avg;
|
||||
}
|
||||
|
|
@ -202,7 +202,7 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn
|
|||
short analog1[960];
|
||||
short analog2[960];
|
||||
short analog3[960];
|
||||
short sample = 0;
|
||||
short sample = 0;
|
||||
|
||||
state->last_cc_sync_time = time(NULL);
|
||||
state->last_vc_sync_time = time(NULL);
|
||||
|
|
@ -217,7 +217,7 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn
|
|||
fprintf (stderr, "\n");
|
||||
|
||||
while (!exitflag && count > 0)
|
||||
{
|
||||
{
|
||||
//this will only work on 48k/1 short output
|
||||
if (opts->audio_in_type == 0)
|
||||
{
|
||||
|
|
@ -243,7 +243,7 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn
|
|||
}
|
||||
|
||||
//NOTE: The core dumps observed previously were due to SDR++ Remote Server connection dropping due to Internet/Other issues
|
||||
//and unlike in the main livescanner loop where it just hangs, this loop will cause a core dump. The observed issue
|
||||
//and unlike in the main livescanner loop where it just hangs, this loop will cause a core dump. The observed issue
|
||||
//has not occurred when using SDR++ on local hardware, just the remote server software over the Internet.
|
||||
|
||||
//NOTE: The fix below does not apply to above observed issue, as the TCP connection will not drop, there will just
|
||||
|
|
@ -291,7 +291,7 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn
|
|||
}
|
||||
analog3[i] = sample;
|
||||
}
|
||||
|
||||
|
||||
//this rms will only work properly (for now) with squelch enabled in SDR++
|
||||
rms = gen_rms(analog3, 960, 1);
|
||||
}
|
||||
|
|
@ -427,7 +427,7 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn
|
|||
fprintf (stderr, "%s", KNRM);
|
||||
|
||||
if (count > 0) fprintf (stderr, "\n");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -437,7 +437,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
unsigned long long int fr_1 = 0xFFFFFFFFFF; //40-bit frames
|
||||
unsigned long long int fr_2 = 0; //each is a 40 bit frame that repeats 3 times
|
||||
unsigned long long int fr_3 = 0; //two messages per frame
|
||||
unsigned long long int fr_4 = 0xFFFFFFFFFF;
|
||||
unsigned long long int fr_4 = 0xFFFFFFFFFF;
|
||||
unsigned long long int fr_5 = 0;
|
||||
unsigned long long int fr_6 = 0;
|
||||
|
||||
|
|
@ -473,18 +473,18 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
{
|
||||
//only fr_1 and fr4 are going to matter
|
||||
fr_1 = fr_1 << 1;
|
||||
fr_1 = fr_1 | edacs_bit[i];
|
||||
fr_1 = fr_1 | edacs_bit[i];
|
||||
fr_2 = fr_2 << 1;
|
||||
fr_2 = fr_2 | edacs_bit[i+40];
|
||||
fr_3 = fr_3 << 1;
|
||||
fr_3 = fr_3 | edacs_bit[i+80];
|
||||
|
||||
fr_4 = fr_4 << 1;
|
||||
fr_4 = fr_4 | edacs_bit[i+120];
|
||||
|
||||
fr_4 = fr_4 << 1;
|
||||
fr_4 = fr_4 | edacs_bit[i+120];
|
||||
fr_5 = fr_5 << 1;
|
||||
fr_5 = fr_5 | edacs_bit[i+160];
|
||||
fr_6 = fr_6 << 1;
|
||||
fr_6 = fr_6 | edacs_bit[i+200];
|
||||
fr_6 = fr_6 | edacs_bit[i+200];
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -508,7 +508,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
else //BCH Pass, continue from here.
|
||||
{
|
||||
|
||||
//Auto Detection Modes Have Been Removed due to reliability issues,
|
||||
//Auto Detection Modes Have Been Removed due to reliability issues,
|
||||
//users will now need to manually specify these options:
|
||||
/*
|
||||
-fh Decode only EDACS Standard/ProVoice*\n");
|
||||
|
|
@ -521,7 +521,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
|
||||
//TODO: Consider re-adding the auto code to make a suggestion to users
|
||||
//as to which mode to proceed in?
|
||||
|
||||
|
||||
//Color scheme:
|
||||
// - KRED - critical information (emergency, failsoft, etc)
|
||||
// - KYEL - system data
|
||||
|
|
@ -536,7 +536,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
fr_1t = fr_1t ^ fr_esk_mask;
|
||||
fr_4t = fr_4t ^ fr_esk_mask;
|
||||
|
||||
//Start Extended Addressing Mode
|
||||
//Start Extended Addressing Mode
|
||||
if (state->ea_mode == 1)
|
||||
{
|
||||
unsigned char mt1 = (fr_1t & 0xF800000000) >> 35;
|
||||
|
|
@ -555,7 +555,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
// MT2 is meaningless if MT1 is not 0x1F
|
||||
if (mt1 == 0x1F)
|
||||
fprintf (stderr, "; MT2: %X) ", mt2);
|
||||
else
|
||||
else
|
||||
fprintf (stderr, ") ");
|
||||
}
|
||||
|
||||
|
|
@ -601,7 +601,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
if (((fr_4t >> 12) & 0x1F) != 0)
|
||||
{
|
||||
state->edacs_cc_lcn = ((fr_4t >> 12) & 0x1F);
|
||||
if (state->edacs_cc_lcn > state->edacs_lcn_count && lcn < 26) //26, or 27. shouldn't matter don't think cc lcn will give a status lcn val
|
||||
if (state->edacs_cc_lcn > state->edacs_lcn_count && lcn < 26) //26, or 27. shouldn't matter don't think cc lcn will give a status lcn val
|
||||
{
|
||||
state->edacs_lcn_count = state->edacs_cc_lcn;
|
||||
}
|
||||
|
|
@ -682,7 +682,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
fprintf (stderr, " FR_4 [%010llX]", fr_4t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//TDMA Group Grant Update (never observed, unknown if ever used on any EDACS system)
|
||||
else if (mt1 == 0x1)
|
||||
|
|
@ -713,7 +713,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
lcn = (fr_1t & 0x3E0000000) >> 29;
|
||||
|
||||
//LCNs greater than 26 are considered status values, "Busy, Queue, Deny, etc"
|
||||
if (lcn > state->edacs_lcn_count && lcn < 26)
|
||||
if (lcn > state->edacs_lcn_count && lcn < 26)
|
||||
{
|
||||
state->edacs_lcn_count = lcn;
|
||||
}
|
||||
|
|
@ -768,7 +768,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
if (state->tg_hold != 0 && state->tg_hold == group) sprintf (mode, "%s", "A");
|
||||
|
||||
//this is working now with the new import setup
|
||||
if (opts->trunk_tune_group_calls == 1 && opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0) ) //DE is digital encrypted, B is block
|
||||
if (opts->trunk_tune_group_calls == 1 && opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0) ) //DE is digital encrypted, B is block
|
||||
{
|
||||
if (lcn > 0 && lcn < 26 && state->edacs_cc_lcn != 0 && state->trunk_lcn_freq[lcn-1] != 0) //don't tune if zero (not loaded or otherwise)
|
||||
{
|
||||
|
|
@ -781,11 +781,11 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
else
|
||||
openWavOutFile48k (opts, state);
|
||||
}
|
||||
|
||||
|
||||
//do condition here, in future, will allow us to use tuning methods as well, or rtl_udp as well
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
SetFreq(opts->rigctl_sockfd, state->trunk_lcn_freq[lcn-1]); //minus one because the lcn index starts at zero
|
||||
state->edacs_tuned_lcn = lcn;
|
||||
opts->p25_is_tuned = 1;
|
||||
|
|
@ -805,7 +805,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
//I-Call Grant Update
|
||||
|
|
@ -814,7 +814,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
lcn = (fr_4t & 0x1F00000000) >> 32;
|
||||
|
||||
//LCNs greater than 26 are considered status values, "Busy, Queue, Deny, etc"
|
||||
if (lcn > state->edacs_lcn_count && lcn < 26)
|
||||
if (lcn > state->edacs_lcn_count && lcn < 26)
|
||||
{
|
||||
state->edacs_lcn_count = lcn;
|
||||
}
|
||||
|
|
@ -843,7 +843,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
if (opts->trunk_use_allow_list == 1) sprintf (mode, "%s", "B");
|
||||
|
||||
//this is working now with the new import setup
|
||||
if (opts->trunk_tune_private_calls == 1 && opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0) ) //DE is digital encrypted, B is block
|
||||
if (opts->trunk_tune_private_calls == 1 && opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0) ) //DE is digital encrypted, B is block
|
||||
{
|
||||
if (lcn > 0 && lcn < 26 && state->edacs_cc_lcn != 0 && state->trunk_lcn_freq[lcn-1] != 0) //don't tune if zero (not loaded or otherwise)
|
||||
{
|
||||
|
|
@ -856,11 +856,11 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
else
|
||||
openWavOutFile48k (opts, state);
|
||||
}
|
||||
|
||||
|
||||
//do condition here, in future, will allow us to use tuning methods as well, or rtl_udp as well
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
SetFreq(opts->rigctl_sockfd, state->trunk_lcn_freq[lcn-1]); //minus one because the lcn index starts at zero
|
||||
state->edacs_tuned_lcn = lcn;
|
||||
opts->p25_is_tuned = 1;
|
||||
|
|
@ -897,7 +897,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
lcn = (fr_1t & 0x3E0000000) >> 29;
|
||||
|
||||
//LCNs greater than 26 are considered status values, "Busy, Queue, Deny, etc"
|
||||
if (lcn > state->edacs_lcn_count && lcn < 26)
|
||||
if (lcn > state->edacs_lcn_count && lcn < 26)
|
||||
{
|
||||
state->edacs_lcn_count = lcn;
|
||||
}
|
||||
|
|
@ -914,7 +914,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
else fprintf (stderr, " Digital System All-Call");
|
||||
if (is_update == 0) fprintf (stderr, " Assignment");
|
||||
else fprintf (stderr, " Update");
|
||||
|
||||
|
||||
fprintf (stderr, " :: Source [%08d] LCN [%02d]%s", source, lcn, get_lcn_status_string(lcn));
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
|
||||
|
|
@ -925,7 +925,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
if (opts->trunk_use_allow_list == 1) sprintf (mode, "%s", "A");
|
||||
|
||||
//this is working now with the new import setup
|
||||
if (opts->trunk_tune_group_calls == 1 && opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0) ) //DE is digital encrypted, B is block
|
||||
if (opts->trunk_tune_group_calls == 1 && opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0) ) //DE is digital encrypted, B is block
|
||||
{
|
||||
if (lcn > 0 && lcn < 26 && state->edacs_cc_lcn != 0 && state->trunk_lcn_freq[lcn-1] != 0) //don't tune if zero (not loaded or otherwise)
|
||||
{
|
||||
|
|
@ -938,11 +938,11 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
else
|
||||
openWavOutFile48k (opts, state);
|
||||
}
|
||||
|
||||
|
||||
//do condition here, in future, will allow us to use tuning methods as well, or rtl_udp as well
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
SetFreq(opts->rigctl_sockfd, state->trunk_lcn_freq[lcn-1]); //minus one because the lcn index starts at zero
|
||||
state->edacs_tuned_lcn = lcn;
|
||||
opts->p25_is_tuned = 1;
|
||||
|
|
@ -962,7 +962,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
//Login
|
||||
|
|
@ -1055,7 +1055,78 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
}
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
|
||||
// TODO: Actually process the call
|
||||
//LCNs >= 26 are reserved to indicate status (queued, busy, denied, etc)
|
||||
if (lcn > state->edacs_lcn_count && lcn < 26)
|
||||
{
|
||||
state->edacs_lcn_count = lcn;
|
||||
}
|
||||
state->edacs_vc_lcn = lcn;
|
||||
state->lasttg = group;
|
||||
state->lastsrc = lid;
|
||||
|
||||
char mode[8]; //allow, block, digital enc
|
||||
sprintf (mode, "%s", "");
|
||||
|
||||
//if we are using allow/whitelist mode, then write 'B' to mode for block
|
||||
//comparison below will look for an 'A' to write to mode if it is allowed
|
||||
if (opts->trunk_use_allow_list == 1) sprintf (mode, "%s", "B");
|
||||
|
||||
//Get group mode for calls that are in the allow/whitelist
|
||||
for (int i = 0; i < state->group_tally; i++)
|
||||
{
|
||||
if (state->group_array[i].groupNumber == group)
|
||||
{
|
||||
strcpy (mode, state->group_array[i].groupMode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//TG hold on EDACS Standard/Net -- block non-matching target, allow matching group
|
||||
if (state->tg_hold != 0 && state->tg_hold != group) sprintf (mode, "%s", "B");
|
||||
if (state->tg_hold != 0 && state->tg_hold == group) sprintf (mode, "%s", "A");
|
||||
|
||||
//NOTE: Restructured below so that analog and digital are handled the same, just that when
|
||||
//its analog, it will now start edacs_analog which will while loop analog samples until
|
||||
//signal level drops (RMS, or a dotting sequence is detected)
|
||||
|
||||
//this is working now with the new import setup
|
||||
if (opts->trunk_tune_group_calls == 1 && opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0) ) //DE is digital encrypted, B is block
|
||||
{
|
||||
if (lcn > 0 && lcn < 26 && state->edacs_cc_lcn != 0 && state->trunk_lcn_freq[lcn-1] != 0) //don't tune if zero (not loaded or otherwise)
|
||||
{
|
||||
//openwav file and do per call right here
|
||||
if (opts->dmr_stereo_wav == 1 && (opts->use_rigctl == 1 || opts->audio_in_type == 3))
|
||||
{
|
||||
sprintf (opts->wav_out_file, "./WAV/%s %s EDACS Site %lld TG %04d SRC %05d.wav", getDateE(), timestr, state->edacs_site_id, group, lid);
|
||||
if (is_digital == 0) openWavOutFile48k (opts, state); //analog at 48k
|
||||
else openWavOutFile (opts, state); //digital
|
||||
}
|
||||
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
//only set bandwidth IF we have an original one to fall back to (experimental, but requires user to set the -B 12000 or -B 24000 value manually)
|
||||
if (opts->setmod_bw != 0)
|
||||
{
|
||||
if (is_digital == 0) SetModulation(opts->rigctl_sockfd, 7000); //narrower bandwidth, but has issues with dotting sequence
|
||||
else SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
}
|
||||
|
||||
SetFreq(opts->rigctl_sockfd, state->trunk_lcn_freq[lcn-1]); //minus one because our index starts at zero
|
||||
state->edacs_tuned_lcn = lcn;
|
||||
opts->p25_is_tuned = 1;
|
||||
if (is_digital == 0) edacs_analog(opts, state, group, lcn);
|
||||
}
|
||||
|
||||
if (opts->audio_in_type == 3) //rtl dongle
|
||||
{
|
||||
#ifdef USE_RTLSDR
|
||||
rtl_dev_tune (opts, state->trunk_lcn_freq[lcn-1]);
|
||||
state->edacs_tuned_lcn = lcn;
|
||||
opts->p25_is_tuned = 1;
|
||||
if (is_digital == 0) edacs_analog(opts, state, group, lcn);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Data Call Channel Assignment (6.2.4.3)
|
||||
else if (mt_a == 0x5)
|
||||
|
|
@ -1114,7 +1185,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
|
||||
//Abstract away to a target, and be sure to check whether it's an individual call later
|
||||
int target = (is_individual_id == 0) ? group : lid;
|
||||
|
||||
|
||||
fprintf (stderr, "%s", KMAG);
|
||||
fprintf (stderr, " Interconnect Channel Assignment :: Type");
|
||||
if (mt_c == 0x2) fprintf (stderr, " [Voice]");
|
||||
|
|
@ -1138,7 +1209,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
|
||||
//Abstract away to a target, and be sure to check whether it's an individual call later
|
||||
int target = (is_individual == 0) ? group : lid;
|
||||
|
||||
|
||||
//Technically only MT-C 0x1 and 0x3 are defined in TSB 69.3 - using and extrapolating on legacy code
|
||||
int is_tx_trunk = (mt_c == 2 || mt_c == 3) ? 1 : 0;
|
||||
int is_digital = (mt_c == 1 || mt_c == 3) ? 1 : 0;
|
||||
|
|
@ -1173,23 +1244,12 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
}
|
||||
state->edacs_vc_lcn = lcn;
|
||||
|
||||
//If we have the same target already in progress, we can keep the source ID since we know it (and don't get
|
||||
//it in this CC message). But if we have a different target, we should clear out to a source ID of 0.
|
||||
if (is_individual == 0)
|
||||
{
|
||||
if (state->lasttg != target) {
|
||||
state->lasttg = target;
|
||||
state->lastsrc = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Use IDs > 10000 to represent i-call targets to differentiate from TGs
|
||||
if (state->lasttg != target + 10000) {
|
||||
state->lasttg = target + 10000;
|
||||
state->lastsrc = 0;
|
||||
}
|
||||
}
|
||||
//Use IDs > 10000 to represent i-call targets to differentiate from TGs
|
||||
if (is_individual == 0) state->lasttg = target;
|
||||
else state->lasttg = target + 10000;
|
||||
|
||||
//Alas, EDACS standard does not provide a source LID on channel updates - try to work around this on the display end instead
|
||||
state->lastsrc = 0;
|
||||
|
||||
char mode[8]; //allow, block, digital enc
|
||||
sprintf (mode, "%s", "");
|
||||
|
|
@ -1259,7 +1319,6 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//System Assigned ID (6.2.4.8)
|
||||
|
|
@ -1455,7 +1514,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
state->edacs_site_id = site_id;
|
||||
|
||||
//LCNs >= 26 are reserved to indicate status (queued, busy, denied, etc)
|
||||
if (state->edacs_cc_lcn > state->edacs_lcn_count && cc_lcn < 26)
|
||||
if (state->edacs_cc_lcn > state->edacs_lcn_count && cc_lcn < 26)
|
||||
{
|
||||
state->edacs_lcn_count = state->edacs_cc_lcn;
|
||||
}
|
||||
|
|
@ -1580,7 +1639,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||
} //end Standard or Networked
|
||||
|
||||
//let users know they need to select an operational mode with the switches below
|
||||
else
|
||||
else
|
||||
{
|
||||
fprintf (stderr, " Detected: Use -fh, -fH, -fe, or -fE for std, esk, ea, or ea-esk;");
|
||||
fprintf (stderr, "\n");
|
||||
|
|
@ -1608,13 +1667,13 @@ void eot_cc(dsd_opts * opts, dsd_state * state)
|
|||
//jump back to CC here
|
||||
if (opts->p25_trunk == 1 && state->p25_cc_freq != 0 && opts->p25_is_tuned == 1)
|
||||
{
|
||||
|
||||
|
||||
//rigctl
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
state->lasttg = 0;
|
||||
state->lastsrc = 0;
|
||||
state->payload_algid = 0;
|
||||
state->payload_algid = 0;
|
||||
state->payload_keyid = 0;
|
||||
state->payload_miP = 0;
|
||||
//reset some strings
|
||||
|
|
@ -1625,7 +1684,7 @@ void eot_cc(dsd_opts * opts, dsd_state * state)
|
|||
opts->p25_is_tuned = 0;
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = 0;
|
||||
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
SetFreq(opts->rigctl_sockfd, state->p25_cc_freq);
|
||||
SetFreq(opts->rigctl_sockfd, state->p25_cc_freq);
|
||||
}
|
||||
|
||||
//rtl
|
||||
|
|
@ -1651,4 +1710,4 @@ void eot_cc(dsd_opts * opts, dsd_state * state)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue