From 29b82e272470881362bde843762c18d1a2dfff2f Mon Sep 17 00:00:00 2001 From: Dave van der Locht Date: Fri, 27 May 2022 11:31:27 +0200 Subject: [PATCH 1/3] Added channel interlock functionality New INTERLOCK parameter for config file interlocks all channels with the same interlock number configured to share DCD and PTT signaling. Useful with several setup types where 2 or more channels shouldn't interfere with eachother. For example when radios and/or antennas are shared. --- src/atest.c | 8 ++++++++ src/audio.h | 10 ++++++++++ src/ax25_link.c | 19 +++++++++++++++++++ src/ax25_link.h | 1 + src/config.c | 27 +++++++++++++++++++++++++++ src/hdlc_rec.c | 23 ++++++++++++++++++++--- 6 files changed, 85 insertions(+), 3 deletions(-) diff --git a/src/atest.c b/src/atest.c index 5f2dd054..7ab86b8c 100644 --- a/src/atest.c +++ b/src/atest.c @@ -86,6 +86,7 @@ #include "hdlc_rec.h" + #if 0 /* Typical but not flexible enough. */ struct wav_header { /* .WAV file header. */ @@ -900,6 +901,13 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev } /* end fake dlq_append */ +/* Fake is_channel_busy */ +int is_channel_busy(int chan) +{ + return 0; +} + + void ptt_set (int ot, int chan, int ptt_signal) { // Should only get here for DCD output control. diff --git a/src/audio.h b/src/audio.h index 78327a73..7e4b93a8 100644 --- a/src/audio.h +++ b/src/audio.h @@ -245,6 +245,8 @@ struct audio_s { int passall; /* Allow thru even with bad CRC. */ + /* Interlock channels */ + int interlock; /* Interlock number */ /* Additional properties for transmit. */ @@ -451,6 +453,14 @@ struct audio_s { #define DEFAULT_TXTAIL 10 #define DEFAULT_FULLDUP 0 +/* + * Interlocks are used to 'bind' channels together to share DCD and PTT signaling. + * Useful with several setup types where 2 or more channels shouldn't interfere with eachother. + * For example when radios and/or antennas are shared. + */ + +#define MAX_INTERLOCKS 8 + /* * Note that we have two versions of these in audio.c and audio_win.c. * Use one or the other depending on the platform. diff --git a/src/ax25_link.c b/src/ax25_link.c index 09e71359..dfccf82b 100644 --- a/src/ax25_link.c +++ b/src/ax25_link.c @@ -1998,6 +1998,25 @@ void lm_channel_busy (dlq_item_t *E) } /* end lm_channel_busy */ +/*------------------------------------------------------------------------------ + * + * Name: is_channel_busy + * + * Purpose: Returns DCD or PTT status for channel + * + * Inputs: Channel + * + * Outputs: True when busy, false when free + * + *------------------------------------------------------------------------------*/ + +int is_channel_busy(int chan) +{ + if (ptt_status[chan] || dcd_status[chan]) + return 1; + + return 0; +} /* end is_channel_busy */ /*------------------------------------------------------------------------------ diff --git a/src/ax25_link.h b/src/ax25_link.h index 40fa401b..ae03ec52 100644 --- a/src/ax25_link.h +++ b/src/ax25_link.h @@ -76,6 +76,7 @@ void lm_seize_confirm (dlq_item_t *E); void lm_channel_busy (dlq_item_t *E); +int is_channel_busy(int chan); void dl_timer_expiry (void); diff --git a/src/config.c b/src/config.c index 194d96a7..64562f6c 100644 --- a/src/config.c +++ b/src/config.c @@ -780,6 +780,8 @@ void config_init (char *fname, struct audio_s *p_audio_config, p_audio_config->achan[channel].sanity_test = SANITY_APRS; p_audio_config->achan[channel].passall = 0; + p_audio_config->achan[channel].interlock = 0; + for (ot = 0; ot < NUM_OCTYPES; ot++) { p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_NONE; strlcpy (p_audio_config->achan[channel].octrl[ot].ptt_device, "", sizeof(p_audio_config->achan[channel].octrl[ot].ptt_device)); @@ -1729,6 +1731,31 @@ void config_init (char *fname, struct audio_s *p_audio_config, } } +/* + * INTERLOCK n + * + * Interlocks channels with the same interlock number (n) to share DCD and PTT signaling. + */ + + else if (strcasecmp(t, "INTERLOCK") == 0) { + int n; + t = split(NULL,0); + if (t == NULL) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Line %d: Missing number for INTERLOCK command.\n", line); + continue; + } + n = atoi(t); + if (n >= 0 && n <= MAX_INTERLOCKS) { + p_audio_config->achan[channel].interlock = n; + } + else { + p_audio_config->achan[channel].interlock = 0; + text_color_set(DW_COLOR_ERROR); + dw_printf ("Line %d: Invalid number for INTERLOCK. Using %d.\n", + line, p_audio_config->achan[channel].interlock); + } + } /* * PTT - Push To Talk signal line. diff --git a/src/hdlc_rec.c b/src/hdlc_rec.c index d87a1b50..65493399 100644 --- a/src/hdlc_rec.c +++ b/src/hdlc_rec.c @@ -47,6 +47,7 @@ #include "ptt.h" #include "fx25.h" #include "il2p.h" +#include "ax25_link.h" //#define TEST 1 /* Define for unit testing. */ @@ -791,11 +792,27 @@ int hdlc_rec_data_detect_any (int chan) { int sc; + int ch; + int il; assert (chan >= 0 && chan < MAX_CHANS); - for (sc = 0; sc < num_subchan[chan]; sc++) { - if (composite_dcd[chan][sc] != 0) - return (1); + if (g_audio_p->achan[chan].interlock > 0) { + // Channel has an interlock number configured, proceed checking interlocked channels + il = g_audio_p->achan[chan].interlock; + + for (ch = 0; ch < MAX_CHANS; ch++) { + if (g_audio_p->achan[ch].interlock == il) { + // Check DCD and PTT state at data link state machine + if (is_channel_busy(ch)) + return (1); + } + } + } else { + // No interlock + for (sc = 0; sc < num_subchan[chan]; sc++) { + if (composite_dcd[chan][sc] != 0) + return (1); + } } if (get_input(ICTYPE_TXINH, chan) == 1) return (1); From ed9618d75e54dc28245bdddf9ba06dc28ba2af96 Mon Sep 17 00:00:00 2001 From: Dave van der Locht Date: Fri, 27 May 2022 11:33:50 +0200 Subject: [PATCH 2/3] Extended rrbb_new() memory leak detection boundary A value of delete_count + 100 seems to give issues with multiple channels and freq. offset decoding configured. Extended to 168 for testing a max. with 3 channels and 7 offset decoders p/channel --- src/rrbb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/rrbb.c b/src/rrbb.c index 2047d69f..37814bfb 100644 --- a/src/rrbb.c +++ b/src/rrbb.c @@ -101,7 +101,11 @@ rrbb_t rrbb_new (int chan, int subchan, int slice, int is_scrambled, int descram new_count++; - if (new_count > delete_count + 100) { + /* + A value of delete_count + 100 seems to give issues with multiple channels and freq. offset decoding configured + extended to 168 for testing a max. with 3 channels and 7 offset decoders p/channel + */ + if (new_count > delete_count + 168) { text_color_set(DW_COLOR_ERROR); dw_printf ("MEMORY LEAK, rrbb_new, new_count=%d, delete_count=%d\n", new_count, delete_count); } From 675e5484ca6b99cf04a8ce53832b175d08a495c5 Mon Sep 17 00:00:00 2001 From: dvanderlocht Date: Thu, 15 Sep 2022 20:12:27 +0200 Subject: [PATCH 3/3] Fixes bug in added channel INTERLOCK functionality DCD state could get stuck which blocked PTT, now fixed. --- src/atest.c | 8 ++++++++ src/audio.h | 10 ++++++++++ src/ax25_link.c | 19 +++++++++++++++++++ src/ax25_link.h | 1 + src/config.c | 29 +++++++++++++++++++++++++++++ src/hdlc_rec.c | 30 +++++++++++++++++++++++++----- src/rrbb.c | 6 +++++- 7 files changed, 97 insertions(+), 6 deletions(-) diff --git a/src/atest.c b/src/atest.c index 5f2dd054..7ab86b8c 100644 --- a/src/atest.c +++ b/src/atest.c @@ -86,6 +86,7 @@ #include "hdlc_rec.h" + #if 0 /* Typical but not flexible enough. */ struct wav_header { /* .WAV file header. */ @@ -900,6 +901,13 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev } /* end fake dlq_append */ +/* Fake is_channel_busy */ +int is_channel_busy(int chan) +{ + return 0; +} + + void ptt_set (int ot, int chan, int ptt_signal) { // Should only get here for DCD output control. diff --git a/src/audio.h b/src/audio.h index 78327a73..7e4b93a8 100644 --- a/src/audio.h +++ b/src/audio.h @@ -245,6 +245,8 @@ struct audio_s { int passall; /* Allow thru even with bad CRC. */ + /* Interlock channels */ + int interlock; /* Interlock number */ /* Additional properties for transmit. */ @@ -451,6 +453,14 @@ struct audio_s { #define DEFAULT_TXTAIL 10 #define DEFAULT_FULLDUP 0 +/* + * Interlocks are used to 'bind' channels together to share DCD and PTT signaling. + * Useful with several setup types where 2 or more channels shouldn't interfere with eachother. + * For example when radios and/or antennas are shared. + */ + +#define MAX_INTERLOCKS 8 + /* * Note that we have two versions of these in audio.c and audio_win.c. * Use one or the other depending on the platform. diff --git a/src/ax25_link.c b/src/ax25_link.c index 09e71359..fb06e63c 100644 --- a/src/ax25_link.c +++ b/src/ax25_link.c @@ -1998,6 +1998,25 @@ void lm_channel_busy (dlq_item_t *E) } /* end lm_channel_busy */ +/*------------------------------------------------------------------------------ + * + * Name: is_channel_busy + * + * Purpose: Returns PTT status for channel + * + * Inputs: Channel + * + * Outputs: True when busy, false when free + * + *------------------------------------------------------------------------------*/ + +int is_channel_busy(int chan) +{ + if (ptt_status[chan]) + return 1; + + return 0; +} /* end is_channel_busy */ /*------------------------------------------------------------------------------ diff --git a/src/ax25_link.h b/src/ax25_link.h index 40fa401b..ae03ec52 100644 --- a/src/ax25_link.h +++ b/src/ax25_link.h @@ -76,6 +76,7 @@ void lm_seize_confirm (dlq_item_t *E); void lm_channel_busy (dlq_item_t *E); +int is_channel_busy(int chan); void dl_timer_expiry (void); diff --git a/src/config.c b/src/config.c index 194d96a7..82bc30bd 100644 --- a/src/config.c +++ b/src/config.c @@ -780,6 +780,8 @@ void config_init (char *fname, struct audio_s *p_audio_config, p_audio_config->achan[channel].sanity_test = SANITY_APRS; p_audio_config->achan[channel].passall = 0; + p_audio_config->achan[channel].interlock = 0; + for (ot = 0; ot < NUM_OCTYPES; ot++) { p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_NONE; strlcpy (p_audio_config->achan[channel].octrl[ot].ptt_device, "", sizeof(p_audio_config->achan[channel].octrl[ot].ptt_device)); @@ -1729,6 +1731,33 @@ void config_init (char *fname, struct audio_s *p_audio_config, } } +/* + * INTERLOCK n + * + * Interlocks channels with the same interlock number (n) to share DCD and PTT signaling. + * Useful with several setup types where 2 or more channels shouldn't interfere with eachother. + * For example when radios and/or antennas are shared. + */ + + else if (strcasecmp(t, "INTERLOCK") == 0) { + int n; + t = split(NULL,0); + if (t == NULL) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Line %d: Missing number for INTERLOCK command.\n", line); + continue; + } + n = atoi(t); + if (n >= 0 && n <= MAX_INTERLOCKS) { + p_audio_config->achan[channel].interlock = n; + } + else { + p_audio_config->achan[channel].interlock = 0; + text_color_set(DW_COLOR_ERROR); + dw_printf ("Line %d: Invalid number for INTERLOCK. Using %d.\n", + line, p_audio_config->achan[channel].interlock); + } + } /* * PTT - Push To Talk signal line. diff --git a/src/hdlc_rec.c b/src/hdlc_rec.c index d87a1b50..fb495f52 100644 --- a/src/hdlc_rec.c +++ b/src/hdlc_rec.c @@ -47,6 +47,7 @@ #include "ptt.h" #include "fx25.h" #include "il2p.h" +#include "ax25_link.h" //#define TEST 1 /* Define for unit testing. */ @@ -791,11 +792,32 @@ int hdlc_rec_data_detect_any (int chan) { int sc; + int ch; + int il; assert (chan >= 0 && chan < MAX_CHANS); - for (sc = 0; sc < num_subchan[chan]; sc++) { - if (composite_dcd[chan][sc] != 0) - return (1); + if (g_audio_p->achan[chan].interlock > 0) { + // Channel has an interlock number configured, proceed checking interlocked channels + il = g_audio_p->achan[chan].interlock; + + for (ch = 0; ch < MAX_CHANS; ch++) { + if (g_audio_p->achan[ch].interlock == il) { + // Check DCD state + for (sc = 0; sc < num_subchan[ch]; sc++) { + if (composite_dcd[ch][sc] != 0) + return (1); + } + // Check PTT state at data link state machine + if (is_channel_busy(ch)) + return (1); + } + } + } else { + // No interlock + for (sc = 0; sc < num_subchan[chan]; sc++) { + if (composite_dcd[chan][sc] != 0) + return (1); + } } if (get_input(ICTYPE_TXINH, chan) == 1) return (1); @@ -805,5 +827,3 @@ int hdlc_rec_data_detect_any (int chan) } /* end hdlc_rec_data_detect_any */ /* end hdlc_rec.c */ - - diff --git a/src/rrbb.c b/src/rrbb.c index 2047d69f..37814bfb 100644 --- a/src/rrbb.c +++ b/src/rrbb.c @@ -101,7 +101,11 @@ rrbb_t rrbb_new (int chan, int subchan, int slice, int is_scrambled, int descram new_count++; - if (new_count > delete_count + 100) { + /* + A value of delete_count + 100 seems to give issues with multiple channels and freq. offset decoding configured + extended to 168 for testing a max. with 3 channels and 7 offset decoders p/channel + */ + if (new_count > delete_count + 168) { text_color_set(DW_COLOR_ERROR); dw_printf ("MEMORY LEAK, rrbb_new, new_count=%d, delete_count=%d\n", new_count, delete_count); }