diff --git a/src/atest.c b/src/atest.c index 5f2dd05..7ab86b8 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 78327a7..7e4b93a 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 09e7135..dfccf82 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 40fa401..ae03ec5 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 194d96a..64562f6 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 d87a1b5..6549339 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);