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:
ilyacodes 2024-03-24 17:48:46 -04:00 committed by GitHub
parent 8d432e8b3e
commit c8d00846b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 246 additions and 178 deletions

View File

@ -7,6 +7,9 @@
*
* LWVMOBILE
* 2022-08 DSD-FME Florida Man Edition
*
* ilyacodes
* 2024-03 EDACS-FME display improvements
*-----------------------------------------------------------------------------*/
@ -2008,6 +2011,12 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
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;
//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);
@ -3493,7 +3502,7 @@ 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)

View File

@ -17,7 +17,7 @@
* 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"
@ -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)
@ -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;
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)