Full Duplex.

This commit is contained in:
wb2osz 2017-10-18 20:50:59 -04:00
parent 59d6708698
commit f6c0049e40
7 changed files with 78 additions and 16 deletions

View File

@ -13,6 +13,8 @@ This is a snapshot of ongoing development towards version of 1.5. Some features
- PTT using GPIO pin of CM108/CM119 (e.g. DMK URI, RB-USB RIM) - PTT using GPIO pin of CM108/CM119 (e.g. DMK URI, RB-USB RIM)
- Full Duplex operation. (Put "FULLDUP ON" in channel section of configuration file.)
### Bugs Fixed: ### ### Bugs Fixed: ###

View File

@ -281,7 +281,10 @@ struct audio_s {
/* are done sending the data. This is to avoid */ /* are done sending the data. This is to avoid */
/* dropping PTT too soon and chopping off the end */ /* dropping PTT too soon and chopping off the end */
/* of the frame. Again 10 mS units. */ /* of the frame. Again 10 mS units. */
/* At this point, I'm thinking of 10 as the default. */ /* At this point, I'm thinking of 10 (= 100 mS) as the default */
/* because we're not quite sure when the soundcard audio stops. */
int fulldup; /* Full Duplex. */
} achan[MAX_CHANS]; } achan[MAX_CHANS];
@ -368,7 +371,7 @@ struct audio_s {
#define DEFAULT_PERSIST 63 #define DEFAULT_PERSIST 63
#define DEFAULT_TXDELAY 30 #define DEFAULT_TXDELAY 30
#define DEFAULT_TXTAIL 10 #define DEFAULT_TXTAIL 10
#define DEFAULT_FULLDUP 0
/* /*
* Note that we have two versions of these in audio.c and audio_win.c. * Note that we have two versions of these in audio.c and audio_win.c.

View File

@ -794,6 +794,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
p_audio_config->achan[channel].persist = DEFAULT_PERSIST; p_audio_config->achan[channel].persist = DEFAULT_PERSIST;
p_audio_config->achan[channel].txdelay = DEFAULT_TXDELAY; p_audio_config->achan[channel].txdelay = DEFAULT_TXDELAY;
p_audio_config->achan[channel].txtail = DEFAULT_TXTAIL; p_audio_config->achan[channel].txtail = DEFAULT_TXTAIL;
p_audio_config->achan[channel].fulldup = DEFAULT_FULLDUP;
} }
/* First channel should always be valid. */ /* First channel should always be valid. */
@ -1923,7 +1924,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
* *
* TXINH - TX holdoff input * TXINH - TX holdoff input
* *
* xxx GPIO [-]gpio-num (only type supported yet) * TXINH GPIO [-]gpio-num (only type supported so far)
*/ */
else if (strcasecmp(t, "TXINH") == 0) { else if (strcasecmp(t, "TXINH") == 0) {
@ -1966,7 +1967,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
/* /*
* DWAIT - Extra delay for receiver squelch. * DWAIT n - Extra delay for receiver squelch. n = 10 mS units.
*/ */
else if (strcasecmp(t, "DWAIT") == 0) { else if (strcasecmp(t, "DWAIT") == 0) {
@ -1990,7 +1991,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
} }
/* /*
* SLOTTIME - For non-digipeat transmit delay timing. * SLOTTIME n - For non-digipeat transmit delay timing. n = 10 mS units.
*/ */
else if (strcasecmp(t, "SLOTTIME") == 0) { else if (strcasecmp(t, "SLOTTIME") == 0) {
@ -2038,7 +2039,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
} }
/* /*
* TXDELAY - For transmit delay timing. * TXDELAY n - For transmit delay timing. n = 10 mS units.
*/ */
else if (strcasecmp(t, "TXDELAY") == 0) { else if (strcasecmp(t, "TXDELAY") == 0) {
@ -2062,7 +2063,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
} }
/* /*
* TXTAIL - For transmit timing. * TXTAIL n - For transmit timing. n = 10 mS units.
*/ */
else if (strcasecmp(t, "TXTAIL") == 0) { else if (strcasecmp(t, "TXTAIL") == 0) {
@ -2085,6 +2086,30 @@ void config_init (char *fname, struct audio_s *p_audio_config,
} }
} }
/*
* FULLDUP {on|off} - Full Duplex
*/
else if (strcasecmp(t, "FULLDUP") == 0) {
t = split(NULL,0);
if (t == NULL) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Line %d: Missing parameter for FULLDUP command. Expecting ON or OFF.\n", line);
continue;
}
if (strcasecmp(t, "ON") == 0) {
p_audio_config->achan[channel].fulldup = 1;
}
else if (strcasecmp(t, "OFF") == 0) {
p_audio_config->achan[channel].fulldup = 0;
}
else {
p_audio_config->achan[channel].fulldup = 0;
text_color_set(DW_COLOR_ERROR);
dw_printf ("Line %d: Expected ON or OFF for FULLDUP.\n", line);
}
}
/* /*
* SPEECH script * SPEECH script
* *

Binary file not shown.

View File

@ -58,7 +58,8 @@
* Spec says it is obsolete but Xastir * Spec says it is obsolete but Xastir
* sends it and we respect it. * sends it and we respect it.
* *
* _5 FullDuplex Ignored. * _5 FullDuplex Full Duplex. Transmit immediately without
* waiting for channel to be clear.
* *
* _6 SetHardware TNC specific. * _6 SetHardware TNC specific.
* *
@ -644,7 +645,8 @@ void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int cli
case KISS_CMD_FULLDUPLEX: /* 5 = FullDuplex */ case KISS_CMD_FULLDUPLEX: /* 5 = FullDuplex */
text_color_set(DW_COLOR_INFO); text_color_set(DW_COLOR_INFO);
dw_printf ("KISS protocol set FullDuplex = %d, port %d - Ignored\n", kiss_msg[1], port); dw_printf ("KISS protocol set FullDuplex = %d, port %d\n", kiss_msg[1], port);
xmit_set_fulldup (port, kiss_msg[1]);
break; break;
case KISS_CMD_SET_HARDWARE: /* 6 = TNC specific */ case KISS_CMD_SET_HARDWARE: /* 6 = TNC specific */

38
xmit.c
View File

@ -2,7 +2,7 @@
// //
// This file is part of Dire Wolf, an amateur radio packet TNC. // This file is part of Dire Wolf, an amateur radio packet TNC.
// //
// Copyright (C) 2011, 2013, 2014, 2015, 2016 John Langner, WB2OSZ // Copyright (C) 2011, 2013, 2014, 2015, 2016, 2017 John Langner, WB2OSZ
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -101,6 +101,8 @@ static int xmit_txtail[MAX_CHANS]; /* Amount of time to keep transmitting after
/* dropping PTT too soon and chopping off the end */ /* dropping PTT too soon and chopping off the end */
/* of the frame. Again 10 mS units. */ /* of the frame. Again 10 mS units. */
static int xmit_fulldup[MAX_CHANS]; /* Full duplex if non-zero. */
static int xmit_bits_per_sec[MAX_CHANS]; /* Data transmission rate. */ static int xmit_bits_per_sec[MAX_CHANS]; /* Data transmission rate. */
/* Often called baud rate which is equivalent in */ /* Often called baud rate which is equivalent in */
/* this case but could be different with other */ /* this case but could be different with other */
@ -137,7 +139,7 @@ static dw_mutex_t audio_out_dev_mutex[MAX_ADEVS];
static int wait_for_clear_channel (int channel, int slotttime, int persist); static int wait_for_clear_channel (int channel, int slotttime, int persist, int fulldup);
static void xmit_ax25_frames (int c, int p, packet_t pp, int max_bundle); static void xmit_ax25_frames (int c, int p, packet_t pp, int max_bundle);
static int send_one_frame (int c, int p, packet_t pp); static int send_one_frame (int c, int p, packet_t pp);
static void xmit_speech (int c, packet_t pp); static void xmit_speech (int c, packet_t pp);
@ -218,6 +220,7 @@ void xmit_init (struct audio_s *p_modem, int debug_xmit_packet)
xmit_persist[j] = p_modem->achan[j].persist; xmit_persist[j] = p_modem->achan[j].persist;
xmit_txdelay[j] = p_modem->achan[j].txdelay; xmit_txdelay[j] = p_modem->achan[j].txdelay;
xmit_txtail[j] = p_modem->achan[j].txtail; xmit_txtail[j] = p_modem->achan[j].txtail;
xmit_fulldup[j] = p_modem->achan[j].fulldup;
} }
#if DEBUG #if DEBUG
@ -306,6 +309,7 @@ void xmit_init (struct audio_s *p_modem, int debug_xmit_packet)
* xmit_set_persist * xmit_set_persist
* xmit_set_slottime * xmit_set_slottime
* xmit_set_txtail * xmit_set_txtail
* xmit_set_fulldup
* *
* *
* Purpose: The KISS protocol, and maybe others, can specify * Purpose: The KISS protocol, and maybe others, can specify
@ -355,6 +359,13 @@ void xmit_set_txtail (int channel, int value)
} }
} }
void xmit_set_fulldup (int channel, int value)
{
if (channel >= 0 && channel < MAX_CHANS) {
xmit_fulldup[channel] = value;
}
}
/*------------------------------------------------------------------- /*-------------------------------------------------------------------
* *
@ -490,7 +501,7 @@ static void * xmit_thread (void *arg)
* If there is something in the high priority queue, begin transmitting immediately. * If there is something in the high priority queue, begin transmitting immediately.
* Otherwise, wait a random amount of time, in hopes of minimizing collisions. * Otherwise, wait a random amount of time, in hopes of minimizing collisions.
*/ */
ok = wait_for_clear_channel (chan, xmit_slottime[chan], xmit_persist[chan]); ok = wait_for_clear_channel (chan, xmit_slottime[chan], xmit_persist[chan], xmit_fulldup[chan]);
prio = TQ_PRIO_1_LO; prio = TQ_PRIO_1_LO;
pp = tq_remove (chan, TQ_PRIO_0_HI); pp = tq_remove (chan, TQ_PRIO_0_HI);
@ -670,6 +681,8 @@ static void * xmit_thread (void *arg)
* Once we have control of the channel, we might as well keep going. * Once we have control of the channel, we might as well keep going.
* [High] Priority frames will always go to head of the line, * [High] Priority frames will always go to head of the line,
* *
* Version 1.5: Add full duplex option.
*
*--------------------------------------------------------------------*/ *--------------------------------------------------------------------*/
@ -1231,12 +1244,19 @@ static void xmit_dtmf (int c, packet_t pp, int speed)
* slottime - Amount of time to wait for each iteration * slottime - Amount of time to wait for each iteration
* of the waiting algorithm. 10 mSec units. * of the waiting algorithm. 10 mSec units.
* *
* persist - Probability of transmitting * persist - Probability of transmitting.
*
* fulldup - Full duplex. Just start sending immediately.
* *
* Returns: 1 for OK. 0 for timeout. * Returns: 1 for OK. 0 for timeout.
* *
* Description: New in version 1.2: also obtain a lock on audio out device. * Description: New in version 1.2: also obtain a lock on audio out device.
* *
* New in version 1.5: full duplex.
* Just start transmitting rather than waiting for clear channel.
* This would only be appropriate when transmit and receive are
* using different radio freqencies. e.g. VHF up, UHF down satellite.
*
* Transmit delay algorithm: * Transmit delay algorithm:
* *
* Wait for channel to be clear. * Wait for channel to be clear.
@ -1271,10 +1291,17 @@ static void xmit_dtmf (int c, packet_t pp, int speed)
#define WAIT_TIMEOUT_MS (60 * 1000) #define WAIT_TIMEOUT_MS (60 * 1000)
#define WAIT_CHECK_EVERY_MS 10 #define WAIT_CHECK_EVERY_MS 10
static int wait_for_clear_channel (int chan, int slottime, int persist) static int wait_for_clear_channel (int chan, int slottime, int persist, int fulldup)
{ {
int n = 0; int n = 0;
/*
* For dull duplex we skip the channel busy check and random wait.
* We still need to wait if operating in stereo and the other audio
* half is busy.
*/
if ( ! fulldup) {
start_over_again: start_over_again:
while (hdlc_rec_data_detect_any(chan)) { while (hdlc_rec_data_detect_any(chan)) {
@ -1318,6 +1345,7 @@ start_over_again:
break; break;
} }
} }
}
/* /*
* This is to prevent two channels from transmitting at the same time * This is to prevent two channels from transmitting at the same time

2
xmit.h
View File

@ -16,6 +16,8 @@ extern void xmit_set_slottime (int channel, int value);
extern void xmit_set_txtail (int channel, int value); extern void xmit_set_txtail (int channel, int value);
extern void xmit_set_fulldup (int channel, int value);
extern int xmit_speak_it (char *script, int c, char *msg); extern int xmit_speak_it (char *script, int c, char *msg);