mirror of https://github.com/wb2osz/direwolf.git
Replace channel valid boolean with more versatile enum.
This commit is contained in:
parent
d6ea439f98
commit
ad12fa86d6
6
atest.c
6
atest.c
|
@ -564,8 +564,10 @@ int main (int argc, char *argv[])
|
||||||
my_audio_config.adev[0].bits_per_sample = format.wbitspersample;
|
my_audio_config.adev[0].bits_per_sample = format.wbitspersample;
|
||||||
my_audio_config.adev[0].num_channels = format.nchannels;
|
my_audio_config.adev[0].num_channels = format.nchannels;
|
||||||
|
|
||||||
my_audio_config.achan[0].valid = 1;
|
my_audio_config.achan[0].medium = MEDIUM_RADIO;
|
||||||
if (format.nchannels == 2) my_audio_config.achan[1].valid = 1;
|
if (format.nchannels == 2) {
|
||||||
|
my_audio_config.achan[1].medium = MEDIUM_RADIO;
|
||||||
|
}
|
||||||
|
|
||||||
text_color_set(DW_COLOR_INFO);
|
text_color_set(DW_COLOR_INFO);
|
||||||
dw_printf ("%d samples per second. %d bits per sample. %d audio channels.\n",
|
dw_printf ("%d samples per second. %d bits per sample. %d audio channels.\n",
|
||||||
|
|
25
audio.h
25
audio.h
|
@ -53,6 +53,13 @@ typedef enum retry_e {
|
||||||
RETRY_INVERT_TWO_SEP=4,
|
RETRY_INVERT_TWO_SEP=4,
|
||||||
RETRY_MAX = 5} retry_t;
|
RETRY_MAX = 5} retry_t;
|
||||||
|
|
||||||
|
// Type of communication medium associated with the channel.
|
||||||
|
|
||||||
|
enum medium_e { MEDIUM_NONE = 0, // Channel is not valid for use.
|
||||||
|
MEDIUM_RADIO, // Internal modem for radio.
|
||||||
|
MEDIUM_IGATE, // Access IGate as ordinary channel.
|
||||||
|
MEDIUM_NETTNC }; // Remote network TNC. (possible future)
|
||||||
|
|
||||||
|
|
||||||
typedef enum sanity_e { SANITY_APRS, SANITY_AX25, SANITY_NONE } sanity_t;
|
typedef enum sanity_e { SANITY_APRS, SANITY_AX25, SANITY_NONE } sanity_t;
|
||||||
|
|
||||||
|
@ -102,19 +109,31 @@ struct audio_s {
|
||||||
/* Command line option uses "strftime" format string. */
|
/* Command line option uses "strftime" format string. */
|
||||||
|
|
||||||
|
|
||||||
/* Properties for each audio channel, common to receive and transmit. */
|
/* Properties for each channel, common to receive and transmit. */
|
||||||
/* Can be different for each radio channel. */
|
/* Can be different for each radio channel. */
|
||||||
|
|
||||||
|
/* originally a "channel" was always connected to an internal modem. */
|
||||||
|
/* In version 1.6, this is generalized so that a channel (as seen by client application) */
|
||||||
|
/* can be connected to something else. Initially, this will allow application */
|
||||||
|
/* access to the IGate. Later we might have network TNCs or other internal functions. */
|
||||||
|
|
||||||
|
|
||||||
struct achan_param_s {
|
struct achan_param_s {
|
||||||
|
|
||||||
int valid; /* Is this channel valid? */
|
// Originally there was a boolean, called "valid", to indicate that the
|
||||||
|
// channel is valid. This has been replaced with the new "medium" which
|
||||||
|
// will allow channels to correspond to things other than internal modems.
|
||||||
|
|
||||||
|
enum medium_e medium; // MEDIUM_NONE for invalid.
|
||||||
|
// MEDIUM_RADIO for internal modem. (only possibility earlier)
|
||||||
|
// MEDIUM_IGATE allows application access to IGate.
|
||||||
|
|
||||||
|
|
||||||
char mycall[AX25_MAX_ADDR_LEN]; /* Call associated with this radio channel. */
|
char mycall[AX25_MAX_ADDR_LEN]; /* Call associated with this radio channel. */
|
||||||
/* Could all be the same or different. */
|
/* Could all be the same or different. */
|
||||||
|
|
||||||
|
|
||||||
enum modem_t { MODEM_AFSK, MODEM_BASEBAND, MODEM_SCRAMBLE, MODEM_QPSK, MODEM_8PSK, MODEM_OFF } modem_type;
|
enum modem_t { MODEM_AFSK, MODEM_BASEBAND, MODEM_SCRAMBLE, MODEM_QPSK, MODEM_8PSK, MODEM_OFF, MODEM_16_QAM, MODEM_64_QAM } modem_type;
|
||||||
|
|
||||||
/* Usual AFSK. */
|
/* Usual AFSK. */
|
||||||
/* Baseband signal. Not used yet. */
|
/* Baseband signal. Not used yet. */
|
||||||
|
|
3
beacon.c
3
beacon.c
|
@ -183,7 +183,8 @@ void beacon_init (struct audio_s *pmodem, struct misc_config_s *pconfig, struct
|
||||||
|
|
||||||
if (chan < 0) chan = 0; /* For IGate, use channel 0 call. */
|
if (chan < 0) chan = 0; /* For IGate, use channel 0 call. */
|
||||||
|
|
||||||
if (g_modem_config_p->achan[chan].valid) {
|
if (g_modem_config_p->achan[chan].medium == MEDIUM_RADIO ||
|
||||||
|
g_modem_config_p->achan[chan].medium == MEDIUM_NETTNC) {
|
||||||
|
|
||||||
if (strlen(g_modem_config_p->achan[chan].mycall) > 0 &&
|
if (strlen(g_modem_config_p->achan[chan].mycall) > 0 &&
|
||||||
strcasecmp(g_modem_config_p->achan[chan].mycall, "N0CALL") != 0 &&
|
strcasecmp(g_modem_config_p->achan[chan].mycall, "N0CALL") != 0 &&
|
||||||
|
|
|
@ -129,8 +129,10 @@ void cdigipeater (int from_chan, packet_t pp)
|
||||||
{
|
{
|
||||||
int to_chan;
|
int to_chan;
|
||||||
|
|
||||||
|
// Connected mode is allowed only for channels with internal modem.
|
||||||
|
// It probably wouldn't matter for digipeating but let's keep that rule simple and consistent.
|
||||||
|
|
||||||
if ( from_chan < 0 || from_chan >= MAX_CHANS || ( ! save_audio_config_p->achan[from_chan].valid) ) {
|
if ( from_chan < 0 || from_chan >= MAX_CHANS || save_audio_config_p->achan[from_chan].medium != MEDIUM_RADIO) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("cdigipeater: Did not expect to receive on invalid channel %d.\n", from_chan);
|
dw_printf ("cdigipeater: Did not expect to receive on invalid channel %d.\n", from_chan);
|
||||||
return;
|
return;
|
||||||
|
|
114
config.c
114
config.c
|
@ -757,8 +757,8 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
for (channel=0; channel<MAX_CHANS; channel++) {
|
for (channel=0; channel<MAX_CHANS; channel++) {
|
||||||
int ot, it;
|
int ot, it;
|
||||||
|
|
||||||
p_audio_config->achan[channel].valid = 0; /* One or both channels will be */
|
p_audio_config->achan[channel].medium = MEDIUM_NONE; /* One or both channels will be */
|
||||||
/* set to valid when corresponding */
|
/* set to radio when corresponding */
|
||||||
/* audio device is defined. */
|
/* audio device is defined. */
|
||||||
p_audio_config->achan[channel].modem_type = MODEM_AFSK;
|
p_audio_config->achan[channel].modem_type = MODEM_AFSK;
|
||||||
p_audio_config->achan[channel].mark_freq = DEFAULT_MARK_FREQ; /* -m option */
|
p_audio_config->achan[channel].mark_freq = DEFAULT_MARK_FREQ; /* -m option */
|
||||||
|
@ -803,8 +803,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
/* First channel should always be valid. */
|
/* First channel should always be valid. */
|
||||||
/* If there is no ADEVICE, it uses default device in mono. */
|
/* If there is no ADEVICE, it uses default device in mono. */
|
||||||
|
|
||||||
p_audio_config->achan[0].valid = 1;
|
p_audio_config->achan[0].medium = MEDIUM_RADIO;
|
||||||
|
|
||||||
|
|
||||||
memset (p_digi_config, 0, sizeof(struct digi_config_s)); // APRS digipeater
|
memset (p_digi_config, 0, sizeof(struct digi_config_s)); // APRS digipeater
|
||||||
p_digi_config->dedupe_time = DEFAULT_DEDUPE;
|
p_digi_config->dedupe_time = DEFAULT_DEDUPE;
|
||||||
|
@ -1018,7 +1017,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
p_audio_config->adev[adevice].defined = 1;
|
p_audio_config->adev[adevice].defined = 1;
|
||||||
|
|
||||||
/* First channel of device is valid. */
|
/* First channel of device is valid. */
|
||||||
p_audio_config->achan[ADEVFIRSTCHAN(adevice)].valid = 1;
|
p_audio_config->achan[ADEVFIRSTCHAN(adevice)].medium = MEDIUM_RADIO;
|
||||||
|
|
||||||
strlcpy (p_audio_config->adev[adevice].adevice_in, t, sizeof(p_audio_config->adev[adevice].adevice_in));
|
strlcpy (p_audio_config->adev[adevice].adevice_in, t, sizeof(p_audio_config->adev[adevice].adevice_in));
|
||||||
strlcpy (p_audio_config->adev[adevice].adevice_out, t, sizeof(p_audio_config->adev[adevice].adevice_out));
|
strlcpy (p_audio_config->adev[adevice].adevice_out, t, sizeof(p_audio_config->adev[adevice].adevice_out));
|
||||||
|
@ -1073,7 +1072,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
p_audio_config->adev[adevice].defined = 1;
|
p_audio_config->adev[adevice].defined = 1;
|
||||||
|
|
||||||
/* First channel of device is valid. */
|
/* First channel of device is valid. */
|
||||||
p_audio_config->achan[ADEVFIRSTCHAN(adevice)].valid = 1;
|
p_audio_config->achan[ADEVFIRSTCHAN(adevice)].medium = MEDIUM_RADIO;
|
||||||
|
|
||||||
strlcpy (p_audio_config->adev[adevice].adevice_in, t, sizeof(p_audio_config->adev[adevice].adevice_in));
|
strlcpy (p_audio_config->adev[adevice].adevice_in, t, sizeof(p_audio_config->adev[adevice].adevice_in));
|
||||||
}
|
}
|
||||||
|
@ -1100,7 +1099,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
p_audio_config->adev[adevice].defined = 1;
|
p_audio_config->adev[adevice].defined = 1;
|
||||||
|
|
||||||
/* First channel of device is valid. */
|
/* First channel of device is valid. */
|
||||||
p_audio_config->achan[ADEVFIRSTCHAN(adevice)].valid = 1;
|
p_audio_config->achan[ADEVFIRSTCHAN(adevice)].medium = MEDIUM_RADIO;
|
||||||
|
|
||||||
strlcpy (p_audio_config->adev[adevice].adevice_out, t, sizeof(p_audio_config->adev[adevice].adevice_out));
|
strlcpy (p_audio_config->adev[adevice].adevice_out, t, sizeof(p_audio_config->adev[adevice].adevice_out));
|
||||||
}
|
}
|
||||||
|
@ -1147,9 +1146,9 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
|
|
||||||
/* Set valid channels depending on mono or stereo. */
|
/* Set valid channels depending on mono or stereo. */
|
||||||
|
|
||||||
p_audio_config->achan[ADEVFIRSTCHAN(adevice)].valid = 1;
|
p_audio_config->achan[ADEVFIRSTCHAN(adevice)].medium = MEDIUM_RADIO;
|
||||||
if (n == 2) {
|
if (n == 2) {
|
||||||
p_audio_config->achan[ADEVFIRSTCHAN(adevice) + 1].valid = 1;
|
p_audio_config->achan[ADEVFIRSTCHAN(adevice) + 1].medium = MEDIUM_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1179,7 +1178,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
|
|
||||||
channel = n;
|
channel = n;
|
||||||
|
|
||||||
if ( ! p_audio_config->achan[n].valid) {
|
if (p_audio_config->achan[n].medium != MEDIUM_RADIO) {
|
||||||
|
|
||||||
if ( ! p_audio_config->adev[ACHAN2ADEV(n)].defined) {
|
if ( ! p_audio_config->adev[ACHAN2ADEV(n)].defined) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
@ -2202,7 +2201,11 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
MAX_CHANS-1, line);
|
MAX_CHANS-1, line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( ! p_audio_config->achan[from_chan].valid) {
|
|
||||||
|
// Channels specified must be radio channels or network TNCs.
|
||||||
|
|
||||||
|
if (p_audio_config->achan[from_chan].medium != MEDIUM_RADIO &&
|
||||||
|
p_audio_config->achan[from_chan].medium != MEDIUM_NETTNC) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n",
|
dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n",
|
||||||
line, from_chan);
|
line, from_chan);
|
||||||
|
@ -2222,7 +2225,9 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
MAX_CHANS-1, line);
|
MAX_CHANS-1, line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( ! p_audio_config->achan[to_chan].valid) {
|
|
||||||
|
if (p_audio_config->achan[to_chan].medium != MEDIUM_RADIO &&
|
||||||
|
p_audio_config->achan[to_chan].medium != MEDIUM_NETTNC) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: TO-channel %d is not valid.\n",
|
dw_printf ("Config file, line %d: TO-channel %d is not valid.\n",
|
||||||
line, to_chan);
|
line, to_chan);
|
||||||
|
@ -2341,7 +2346,10 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
MAX_CHANS-1, line);
|
MAX_CHANS-1, line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( ! p_audio_config->achan[from_chan].valid) {
|
|
||||||
|
// Only radio channels are valid for regenerate.
|
||||||
|
|
||||||
|
if (p_audio_config->achan[from_chan].medium != MEDIUM_RADIO) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n",
|
dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n",
|
||||||
line, from_chan);
|
line, from_chan);
|
||||||
|
@ -2361,7 +2369,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
MAX_CHANS-1, line);
|
MAX_CHANS-1, line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( ! p_audio_config->achan[to_chan].valid) {
|
if (p_audio_config->achan[to_chan].medium != MEDIUM_RADIO) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: TO-channel %d is not valid.\n",
|
dw_printf ("Config file, line %d: TO-channel %d is not valid.\n",
|
||||||
line, to_chan);
|
line, to_chan);
|
||||||
|
@ -2400,10 +2408,17 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
MAX_CHANS-1, line);
|
MAX_CHANS-1, line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( ! p_audio_config->achan[from_chan].valid) {
|
|
||||||
|
// For connected mode Link layer, only internal modems should be allowed.
|
||||||
|
// A network TNC probably would not provide information about channel status.
|
||||||
|
// There is discussion about this in the document called
|
||||||
|
// Why-is-9600-only-twice-as-fast-as-1200.pdf
|
||||||
|
|
||||||
|
if (p_audio_config->achan[from_chan].medium != MEDIUM_RADIO) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n",
|
dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n",
|
||||||
line, from_chan);
|
line, from_chan);
|
||||||
|
dw_printf ("Only internal modems can be used for connected mode packet.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2420,10 +2435,11 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
MAX_CHANS-1, line);
|
MAX_CHANS-1, line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( ! p_audio_config->achan[to_chan].valid) {
|
if (p_audio_config->achan[to_chan].medium != MEDIUM_RADIO) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: TO-channel %d is not valid.\n",
|
dw_printf ("Config file, line %d: TO-channel %d is not valid.\n",
|
||||||
line, to_chan);
|
line, to_chan);
|
||||||
|
dw_printf ("Only internal modems can be used for connected mode packet.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2468,11 +2484,24 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
* to include IGate client side. Maybe it should be
|
* to include IGate client side. Maybe it should be
|
||||||
* renamed AFILTER to make it clearer after adding CFILTER.
|
* renamed AFILTER to make it clearer after adding CFILTER.
|
||||||
*
|
*
|
||||||
|
* Both internal modem and NET TNC channels allowed here.
|
||||||
|
* "IG" should be used for the IGate, NOT a virtual channel
|
||||||
|
* assigned to it.
|
||||||
|
*
|
||||||
* CFILTER - Similar for connected moded digipeater.
|
* CFILTER - Similar for connected moded digipeater.
|
||||||
*
|
*
|
||||||
|
* Only internal modems can be used because they provide
|
||||||
|
* information about radio channel status.
|
||||||
|
* A remote network TNC might not provide the necessary
|
||||||
|
* status for correct operation.
|
||||||
|
* There is discussion about this in the document called
|
||||||
|
* Why-is-9600-only-twice-as-fast-as-1200.pdf
|
||||||
|
*
|
||||||
* IGFILTER - APRS-IS (IGate) server side - completely diffeent.
|
* IGFILTER - APRS-IS (IGate) server side - completely diffeent.
|
||||||
* I'm not happy with this name because IG sounds like IGate
|
* I'm not happy with this name because IG sounds like IGate
|
||||||
* which is really the client side. More comments later.
|
* which is really the client side. More comments later.
|
||||||
|
* Maybe it should be called subscribe or something like that
|
||||||
|
* because the subscriptions are cummulative.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
else if (strcasecmp(t, "FILTER") == 0) {
|
else if (strcasecmp(t, "FILTER") == 0) {
|
||||||
|
@ -2497,12 +2526,19 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! p_audio_config->achan[from_chan].valid) {
|
if (p_audio_config->achan[from_chan].medium != MEDIUM_RADIO &&
|
||||||
|
p_audio_config->achan[from_chan].medium != MEDIUM_NETTNC) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n",
|
dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n",
|
||||||
line, from_chan);
|
line, from_chan);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (p_audio_config->achan[from_chan].medium == MEDIUM_IGATE) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Config file, line %d: Use 'IG' rather than %d for FROM-channel.\n",
|
||||||
|
line, from_chan);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t = split(NULL,0);
|
t = split(NULL,0);
|
||||||
|
@ -2522,12 +2558,19 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
MAX_CHANS-1, line);
|
MAX_CHANS-1, line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( ! p_audio_config->achan[to_chan].valid) {
|
if (p_audio_config->achan[to_chan].medium != MEDIUM_RADIO &&
|
||||||
|
p_audio_config->achan[to_chan].medium != MEDIUM_NETTNC) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: TO-channel %d is not valid.\n",
|
dw_printf ("Config file, line %d: TO-channel %d is not valid.\n",
|
||||||
line, to_chan);
|
line, to_chan);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (p_audio_config->achan[to_chan].medium == MEDIUM_IGATE) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Config file, line %d: Use 'IG' rather than %d for TO-channel.\n",
|
||||||
|
line, to_chan);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t = split(NULL,1); /* Take rest of line including spaces. */
|
t = split(NULL,1); /* Take rest of line including spaces. */
|
||||||
|
@ -2578,7 +2621,10 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! p_audio_config->achan[from_chan].valid) {
|
// DO NOT allow a network TNC here.
|
||||||
|
// Must be internal modem to have necessary knowledge about channel status.
|
||||||
|
|
||||||
|
if (p_audio_config->achan[from_chan].medium != MEDIUM_RADIO) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n",
|
dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n",
|
||||||
line, from_chan);
|
line, from_chan);
|
||||||
|
@ -2599,7 +2645,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
MAX_CHANS-1, line);
|
MAX_CHANS-1, line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( ! p_audio_config->achan[to_chan].valid) {
|
if (p_audio_config->achan[to_chan].medium != MEDIUM_RADIO) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: TO-channel %d is not valid.\n",
|
dw_printf ("Config file, line %d: TO-channel %d is not valid.\n",
|
||||||
line, to_chan);
|
line, to_chan);
|
||||||
|
@ -3756,7 +3802,11 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
MAX_CHANS-1, line);
|
MAX_CHANS-1, line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( ! p_audio_config->achan[r].valid) {
|
|
||||||
|
// I suppose we need internal modem channel here.
|
||||||
|
// otherwise a DTMF decoder would not be available.
|
||||||
|
|
||||||
|
if (p_audio_config->achan[r].medium != MEDIUM_RADIO) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: TTOBJ DTMF receive channel %d is not valid.\n",
|
dw_printf ("Config file, line %d: TTOBJ DTMF receive channel %d is not valid.\n",
|
||||||
line, r);
|
line, r);
|
||||||
|
@ -3782,7 +3832,8 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
dw_printf ("Config file: Transmit channel must be in range of 0 to %d on line %d.\n", MAX_CHANS-1, line);
|
dw_printf ("Config file: Transmit channel must be in range of 0 to %d on line %d.\n", MAX_CHANS-1, line);
|
||||||
x = -1;
|
x = -1;
|
||||||
}
|
}
|
||||||
else if ( ! p_audio_config->achan[x].valid) {
|
else if (p_audio_config->achan[x].medium != MEDIUM_RADIO &&
|
||||||
|
p_audio_config->achan[x].medium != MEDIUM_NETTNC) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: TTOBJ transmit channel %d is not valid.\n", line, x);
|
dw_printf ("Config file, line %d: TTOBJ transmit channel %d is not valid.\n", line, x);
|
||||||
x = -1;
|
x = -1;
|
||||||
|
@ -4970,7 +5021,10 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_audio_config->achan[i].valid && strlen(p_igate_config->t2_login) > 0) {
|
/* When IGate is enabled, all radio channels must have a callsign associated. */
|
||||||
|
|
||||||
|
if (strlen(p_igate_config->t2_login) > 0 &&
|
||||||
|
(p_audio_config->achan[i].medium == MEDIUM_RADIO || p_audio_config->achan[i].medium == MEDIUM_NETTNC)) {
|
||||||
|
|
||||||
if (strcmp(p_audio_config->achan[i].mycall, "NOCALL") == 0 || strcmp(p_audio_config->achan[i].mycall, "N0CALL") == 0) {
|
if (strcmp(p_audio_config->achan[i].mycall, "NOCALL") == 0 || strcmp(p_audio_config->achan[i].mycall, "N0CALL") == 0) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
@ -4994,10 +5048,12 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
// Apply default IS>RF IGate filter if none specified. New in 1.4.
|
// Apply default IS>RF IGate filter if none specified. New in 1.4.
|
||||||
// This will handle eventual case of multiple transmit channels.
|
// This will handle eventual case of multiple transmit channels.
|
||||||
|
|
||||||
|
if (strlen(p_igate_config->t2_login) > 0) {
|
||||||
for (j=0; j<MAX_CHANS; j++) {
|
for (j=0; j<MAX_CHANS; j++) {
|
||||||
if (p_audio_config->achan[j].valid && strlen(p_igate_config->t2_login) > 0) {
|
if (p_audio_config->achan[j].medium == MEDIUM_RADIO || p_audio_config->achan[j].medium == MEDIUM_NETTNC) {
|
||||||
if (p_digi_config->filter_str[MAX_CHANS][j] == NULL) {
|
if (p_digi_config->filter_str[MAX_CHANS][j] == NULL) {
|
||||||
p_digi_config->filter_str[MAX_CHANS][j] = strdup("i/30");
|
p_digi_config->filter_str[MAX_CHANS][j] = strdup("i/60");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5085,7 +5141,7 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_
|
||||||
}
|
}
|
||||||
else if (value[0] == 'r' || value[0] == 'R') {
|
else if (value[0] == 'r' || value[0] == 'R') {
|
||||||
int n = atoi(value+1);
|
int n = atoi(value+1);
|
||||||
if ( n < 0 || n >= MAX_CHANS || ! p_audio_config->achan[n].valid) {
|
if ( n < 0 || n >= MAX_CHANS || p_audio_config->achan[n].medium == MEDIUM_NONE) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: Simulated receive on channel %d is not valid.\n", line, n);
|
dw_printf ("Config file, line %d: Simulated receive on channel %d is not valid.\n", line, n);
|
||||||
continue;
|
continue;
|
||||||
|
@ -5095,7 +5151,7 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_
|
||||||
}
|
}
|
||||||
else if (value[0] == 't' || value[0] == 'T' || value[0] == 'x' || value[0] == 'X') {
|
else if (value[0] == 't' || value[0] == 'T' || value[0] == 'x' || value[0] == 'X') {
|
||||||
int n = atoi(value+1);
|
int n = atoi(value+1);
|
||||||
if ( n < 0 || n >= MAX_CHANS || ! p_audio_config->achan[n].valid) {
|
if ( n < 0 || n >= MAX_CHANS || p_audio_config->achan[n].medium == MEDIUM_NONE) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: Send to channel %d is not valid.\n", line, n);
|
dw_printf ("Config file, line %d: Send to channel %d is not valid.\n", line, n);
|
||||||
continue;
|
continue;
|
||||||
|
@ -5106,7 +5162,7 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int n = atoi(value);
|
int n = atoi(value);
|
||||||
if ( n < 0 || n >= MAX_CHANS || ! p_audio_config->achan[n].valid) {
|
if ( n < 0 || n >= MAX_CHANS || p_audio_config->achan[n].medium == MEDIUM_NONE) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: Send to channel %d is not valid.\n", line, n);
|
dw_printf ("Config file, line %d: Send to channel %d is not valid.\n", line, n);
|
||||||
continue;
|
continue;
|
||||||
|
@ -5318,7 +5374,7 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_
|
||||||
|
|
||||||
if (b->sendto_type == SENDTO_XMIT) {
|
if (b->sendto_type == SENDTO_XMIT) {
|
||||||
|
|
||||||
if ( b->sendto_chan < 0 || b->sendto_chan >= MAX_CHANS || ! p_audio_config->achan[b->sendto_chan].valid) {
|
if ( b->sendto_chan < 0 || b->sendto_chan >= MAX_CHANS || p_audio_config->achan[b->sendto_chan].medium == MEDIUM_NONE) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file, line %d: Send to channel %d is not valid.\n", line, b->sendto_chan);
|
dw_printf ("Config file, line %d: Send to channel %d is not valid.\n", line, b->sendto_chan);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
2
demod.c
2
demod.c
|
@ -108,7 +108,7 @@ int demod_init (struct audio_s *pa)
|
||||||
|
|
||||||
for (chan = 0; chan < MAX_CHANS; chan++) {
|
for (chan = 0; chan < MAX_CHANS; chan++) {
|
||||||
|
|
||||||
if (save_audio_config_p->achan[chan].valid) {
|
if (save_audio_config_p->achan[chan].medium == MEDIUM_RADIO) {
|
||||||
|
|
||||||
char *p;
|
char *p;
|
||||||
char just_letters[16];
|
char just_letters[16];
|
||||||
|
|
10
digipeater.c
10
digipeater.c
|
@ -149,11 +149,15 @@ void digipeater (int from_chan, packet_t pp)
|
||||||
|
|
||||||
// dw_printf ("digipeater()\n");
|
// dw_printf ("digipeater()\n");
|
||||||
|
|
||||||
assert (from_chan >= 0 && from_chan < MAX_CHANS);
|
|
||||||
|
|
||||||
if ( ! save_audio_config_p->achan[from_chan].valid) {
|
|
||||||
|
// Network TNC is OK for UI frames where we don't care about timing.
|
||||||
|
|
||||||
|
if ( from_chan < 0 || from_chan >= MAX_CHANS ||
|
||||||
|
(save_audio_config_p->achan[from_chan].medium != MEDIUM_RADIO &&
|
||||||
|
save_audio_config_p->achan[from_chan].medium != MEDIUM_NETTNC)) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("digipeater: Did not expect to receive on invalid channel %d.\n", from_chan);
|
dw_printf ("APRS digipeater: Did not expect to receive on invalid channel %d.\n", from_chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,14 @@
|
||||||
*
|
*
|
||||||
* Purpose: Main program for "Dire Wolf" which includes:
|
* Purpose: Main program for "Dire Wolf" which includes:
|
||||||
*
|
*
|
||||||
* AFSK modem using the "sound card."
|
* Various DSP modems using the "sound card."
|
||||||
* AX.25 encoder/decoder.
|
* AX.25 encoder/decoder.
|
||||||
* APRS data encoder / decoder.
|
* APRS data encoder / decoder.
|
||||||
* APRS digipeater.
|
* APRS digipeater.
|
||||||
* KISS TNC emulator.
|
* KISS TNC emulator.
|
||||||
* APRStt (touch tone input) gateway
|
* APRStt (touch tone input) gateway
|
||||||
* Internet Gateway (IGate)
|
* Internet Gateway (IGate)
|
||||||
|
* Ham Radio of Things - IoT with Ham Radio
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
|
@ -630,7 +631,7 @@ int main (int argc, char *argv[])
|
||||||
if (n_opt != 0) {
|
if (n_opt != 0) {
|
||||||
audio_config.adev[0].num_channels = n_opt;
|
audio_config.adev[0].num_channels = n_opt;
|
||||||
if (n_opt == 2) {
|
if (n_opt == 2) {
|
||||||
audio_config.achan[1].valid = 1;
|
audio_config.achan[1].medium = MEDIUM_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
dtmf.c
2
dtmf.c
|
@ -529,7 +529,7 @@ int main ()
|
||||||
memset (&my_audio_config, 0, sizeof(my_audio_config));
|
memset (&my_audio_config, 0, sizeof(my_audio_config));
|
||||||
my_audio_config.adev[ACHAN2ADEV(c)].defined = 1;
|
my_audio_config.adev[ACHAN2ADEV(c)].defined = 1;
|
||||||
my_audio_config.adev[ACHAN2ADEV(c)].samples_per_sec = 44100;
|
my_audio_config.adev[ACHAN2ADEV(c)].samples_per_sec = 44100;
|
||||||
my_audio_config.achan[c].valid = 1;
|
my_audio_config.achan[c].medium = MEDIUM_RADIO;
|
||||||
my_audio_config.achan[c].dtmf_decode = DTMF_DECODE_ON;
|
my_audio_config.achan[c].dtmf_decode = DTMF_DECODE_ON;
|
||||||
|
|
||||||
dtmf_init(&my_audio_config, 50);
|
dtmf_init(&my_audio_config, 50);
|
||||||
|
|
|
@ -183,7 +183,7 @@ int main(int argc, char **argv)
|
||||||
modem.achan[chan].baud = DEFAULT_BAUD; /* -b option */
|
modem.achan[chan].baud = DEFAULT_BAUD; /* -b option */
|
||||||
}
|
}
|
||||||
|
|
||||||
modem.achan[0].valid = 1;
|
modem.achan[0].medium = MEDIUM_RADIO;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -402,7 +402,7 @@ int main(int argc, char **argv)
|
||||||
case '2': /* -2 for 2 channels of sound */
|
case '2': /* -2 for 2 channels of sound */
|
||||||
|
|
||||||
modem.adev[0].num_channels = 2;
|
modem.adev[0].num_channels = 2;
|
||||||
modem.achan[1].valid = 1;
|
modem.achan[1].medium = MEDIUM_RADIO;
|
||||||
text_color_set(DW_COLOR_INFO);
|
text_color_set(DW_COLOR_INFO);
|
||||||
dw_printf("2 channels of sound rather than 1.\n");
|
dw_printf("2 channels of sound rather than 1.\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -164,7 +164,7 @@ int gen_tone_init (struct audio_s *audio_config_p, int amp, int gen_packets)
|
||||||
|
|
||||||
for (chan = 0; chan < MAX_CHANS; chan++) {
|
for (chan = 0; chan < MAX_CHANS; chan++) {
|
||||||
|
|
||||||
if (audio_config_p->achan[chan].valid) {
|
if (audio_config_p->achan[chan].medium == MEDIUM_RADIO) {
|
||||||
|
|
||||||
int a = ACHAN2ADEV(chan);
|
int a = ACHAN2ADEV(chan);
|
||||||
|
|
||||||
|
@ -291,8 +291,12 @@ void tone_gen_put_bit (int chan, int dat)
|
||||||
int a = ACHAN2ADEV(chan); /* device for channel. */
|
int a = ACHAN2ADEV(chan); /* device for channel. */
|
||||||
|
|
||||||
assert (save_audio_config_p != NULL);
|
assert (save_audio_config_p != NULL);
|
||||||
assert (save_audio_config_p->achan[chan].valid);
|
|
||||||
|
|
||||||
|
if (save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Invalid channel %d for tone generation.\n", chan);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (dat < 0) {
|
if (dat < 0) {
|
||||||
/* Hack to test receive PLL recovery. */
|
/* Hack to test receive PLL recovery. */
|
||||||
|
|
15
hdlc_rec.c
15
hdlc_rec.c
|
@ -33,6 +33,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
//#include "tune.h"
|
||||||
#include "demod.h"
|
#include "demod.h"
|
||||||
#include "hdlc_rec.h"
|
#include "hdlc_rec.h"
|
||||||
#include "hdlc_rec2.h"
|
#include "hdlc_rec2.h"
|
||||||
|
@ -47,7 +48,6 @@
|
||||||
|
|
||||||
//#define TEST 1 /* Define for unit testing. */
|
//#define TEST 1 /* Define for unit testing. */
|
||||||
|
|
||||||
|
|
||||||
//#define DEBUG3 1 /* monitor the data detect signal. */
|
//#define DEBUG3 1 /* monitor the data detect signal. */
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ void hdlc_rec_init (struct audio_s *pa)
|
||||||
for (ch = 0; ch < MAX_CHANS; ch++)
|
for (ch = 0; ch < MAX_CHANS; ch++)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (pa->achan[ch].valid) {
|
if (pa->achan[ch].medium == MEDIUM_RADIO) {
|
||||||
|
|
||||||
num_subchan[ch] = pa->achan[ch].num_subchan;
|
num_subchan[ch] = pa->achan[ch].num_subchan;
|
||||||
|
|
||||||
|
@ -230,13 +230,16 @@ void hdlc_rec_bit (int chan, int subchan, int slice, int raw, int is_scrambled,
|
||||||
|
|
||||||
dbit = (descram == H->prev_descram);
|
dbit = (descram == H->prev_descram);
|
||||||
H->prev_descram = descram;
|
H->prev_descram = descram;
|
||||||
H->prev_raw = raw; }
|
H->prev_raw = raw;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
dbit = (raw == H->prev_raw);
|
dbit = (raw == H->prev_raw);
|
||||||
|
|
||||||
H->prev_raw = raw;
|
H->prev_raw = raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Octets are sent LSB first.
|
* Octets are sent LSB first.
|
||||||
* Shift the most recent 8 bits thru the pattern detector.
|
* Shift the most recent 8 bits thru the pattern detector.
|
||||||
|
@ -289,9 +292,9 @@ void hdlc_rec_bit (int chan, int subchan, int slice, int raw, int is_scrambled,
|
||||||
|
|
||||||
|
|
||||||
//if (H->flag4_det == 0x7e7e7e7e) {
|
//if (H->flag4_det == 0x7e7e7e7e) {
|
||||||
if ((H->flag4_det & 0xffffff00) == 0x7e7e7e00) {
|
if ((H->flag4_det & 0xffffff00) == 0x7e7e7e00) { // three seems good
|
||||||
//if ((H->flag4_det & 0xffff0000) == 0x7e7e0000) {
|
//if ((H->flag4_det & 0xffff0000) == 0x7e7e0000) { // two in a row
|
||||||
|
//if ((H->flag4_det & 0xff000000) == 0x7e000000) { // single flag
|
||||||
if ( ! H->data_detect) {
|
if ( ! H->data_detect) {
|
||||||
H->data_detect = 1;
|
H->data_detect = 1;
|
||||||
dcd_change (chan, subchan, slice, 1);
|
dcd_change (chan, subchan, slice, 1);
|
||||||
|
|
|
@ -586,8 +586,9 @@ void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int cli
|
||||||
|
|
||||||
|
|
||||||
/* Verify that the port (channel) number is valid. */
|
/* Verify that the port (channel) number is valid. */
|
||||||
|
/* Any sort of medium should be OK here. */
|
||||||
|
|
||||||
if (port < 0 || port >= MAX_CHANS || ! save_audio_config_p->achan[port].valid) {
|
if (port < 0 || port >= MAX_CHANS || save_audio_config_p->achan[port].medium == MEDIUM_NONE) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Invalid transmit channel %d from KISS client app.\n", port);
|
dw_printf ("Invalid transmit channel %d from KISS client app.\n", port);
|
||||||
dw_printf ("\n");
|
dw_printf ("\n");
|
||||||
|
|
19
morse.c
19
morse.c
|
@ -312,7 +312,12 @@ static void morse_tone (int chan, int tu, int wpm) {
|
||||||
|
|
||||||
int f1_change_per_sample; // How much to advance phase for each audio sample.
|
int f1_change_per_sample; // How much to advance phase for each audio sample.
|
||||||
|
|
||||||
assert (save_audio_config_p->achan[chan].valid);
|
|
||||||
|
if (save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Invalid channel %d for sending Morse Code.\n", chan);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tone_phase = 0;
|
tone_phase = 0;
|
||||||
|
|
||||||
|
@ -360,7 +365,11 @@ static void morse_quiet (int chan, int tu, int wpm) {
|
||||||
int nsamples;
|
int nsamples;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
assert (save_audio_config_p->achan[chan].valid);
|
if (save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Invalid channel %d for sending Morse Code.\n", chan);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsamples = (int) ((TIME_UNITS_TO_MS(tu,wpm) * (float)save_audio_config_p->adev[a].samples_per_sec / 1000.) + 0.5);
|
nsamples = (int) ((TIME_UNITS_TO_MS(tu,wpm) * (float)save_audio_config_p->adev[a].samples_per_sec / 1000.) + 0.5);
|
||||||
|
|
||||||
|
@ -395,7 +404,11 @@ static void morse_quiet_ms (int chan, int ms) {
|
||||||
int nsamples;
|
int nsamples;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
assert (save_audio_config_p->achan[chan].valid);
|
if (save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Invalid channel %d for sending Morse Code.\n", chan);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsamples = (int) ((ms * (float)save_audio_config_p->adev[a].samples_per_sec / 1000.) + 0.5);
|
nsamples = (int) ((ms * (float)save_audio_config_p->adev[a].samples_per_sec / 1000.) + 0.5);
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ void multi_modem_init (struct audio_s *pa)
|
||||||
hdlc_rec_init (save_audio_config_p);
|
hdlc_rec_init (save_audio_config_p);
|
||||||
|
|
||||||
for (chan=0; chan<MAX_CHANS; chan++) {
|
for (chan=0; chan<MAX_CHANS; chan++) {
|
||||||
if (save_audio_config_p->achan[chan].valid) {
|
if (save_audio_config_p->achan[chan].medium == MEDIUM_RADIO) {
|
||||||
if (save_audio_config_p->achan[chan].baud <= 0) {
|
if (save_audio_config_p->achan[chan].baud <= 0) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf("Internal error, chan=%d, %s, %d\n", chan, __FILE__, __LINE__);
|
dw_printf("Internal error, chan=%d, %s, %d\n", chan, __FILE__, __LINE__);
|
||||||
|
|
38
ptt.c
38
ptt.c
|
@ -725,7 +725,7 @@ void ptt_init (struct audio_s *audio_config_p)
|
||||||
|
|
||||||
for (ch = 0; ch < MAX_CHANS; ch++) {
|
for (ch = 0; ch < MAX_CHANS; ch++) {
|
||||||
|
|
||||||
if (audio_config_p->achan[ch].valid) {
|
if (audio_config_p->achan[ch].medium == MEDIUM_RADIO) {
|
||||||
int ot;
|
int ot;
|
||||||
|
|
||||||
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
||||||
|
@ -756,7 +756,7 @@ void ptt_init (struct audio_s *audio_config_p)
|
||||||
int j, k;
|
int j, k;
|
||||||
|
|
||||||
for (j = ch; j >= 0; j--) {
|
for (j = ch; j >= 0; j--) {
|
||||||
if (audio_config_p->achan[j].valid) {
|
if (audio_config_p->achan[j].medium == MEDIUM_RADIO) {
|
||||||
for (k = ((j==ch) ? (ot - 1) : (NUM_OCTYPES-1)); k >= 0; k--) {
|
for (k = ((j==ch) ? (ot - 1) : (NUM_OCTYPES-1)); k >= 0; k--) {
|
||||||
if (strcmp(audio_config_p->achan[ch].octrl[ot].ptt_device,audio_config_p->achan[j].octrl[k].ptt_device) == 0) {
|
if (strcmp(audio_config_p->achan[ch].octrl[ot].ptt_device,audio_config_p->achan[j].octrl[k].ptt_device) == 0) {
|
||||||
fd = ptt_fd[j][k];
|
fd = ptt_fd[j][k];
|
||||||
|
@ -839,7 +839,7 @@ void ptt_init (struct audio_s *audio_config_p)
|
||||||
|
|
||||||
using_gpio = 0;
|
using_gpio = 0;
|
||||||
for (ch=0; ch<MAX_CHANS; ch++) {
|
for (ch=0; ch<MAX_CHANS; ch++) {
|
||||||
if (save_audio_config_p->achan[ch].valid) {
|
if (save_audio_config_p->achan[ch].medium == MEDIUM_RADIO) {
|
||||||
int ot;
|
int ot;
|
||||||
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
||||||
if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_GPIO) {
|
if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_GPIO) {
|
||||||
|
@ -864,7 +864,7 @@ void ptt_init (struct audio_s *audio_config_p)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (ch = 0; ch < MAX_CHANS; ch++) {
|
for (ch = 0; ch < MAX_CHANS; ch++) {
|
||||||
if (save_audio_config_p->achan[ch].valid) {
|
if (save_audio_config_p->achan[ch].medium == MEDIUM_RADIO) {
|
||||||
|
|
||||||
int ot; // output control type, PTT, DCD, CON, ...
|
int ot; // output control type, PTT, DCD, CON, ...
|
||||||
int it; // input control type
|
int it; // input control type
|
||||||
|
@ -896,7 +896,7 @@ void ptt_init (struct audio_s *audio_config_p)
|
||||||
#if ( defined(__i386__) || defined(__x86_64__) ) && ( defined(__linux__) || defined(__unix__) )
|
#if ( defined(__i386__) || defined(__x86_64__) ) && ( defined(__linux__) || defined(__unix__) )
|
||||||
|
|
||||||
for (ch = 0; ch < MAX_CHANS; ch++) {
|
for (ch = 0; ch < MAX_CHANS; ch++) {
|
||||||
if (save_audio_config_p->achan[ch].valid) {
|
if (save_audio_config_p->achan[ch].medium == MEDIUM_RADIO) {
|
||||||
int ot;
|
int ot;
|
||||||
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
||||||
if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_LPT) {
|
if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_LPT) {
|
||||||
|
@ -911,7 +911,7 @@ void ptt_init (struct audio_s *audio_config_p)
|
||||||
int j, k;
|
int j, k;
|
||||||
|
|
||||||
for (j = ch; j >= 0; j--) {
|
for (j = ch; j >= 0; j--) {
|
||||||
if (audio_config_p->achan[j].valid) {
|
if (audio_config_p->achan[j].medium == MEDIUM_RADIO) {
|
||||||
for (k = ((j==ch) ? (ot - 1) : (NUM_OCTYPES-1)); k >= 0; k--) {
|
for (k = ((j==ch) ? (ot - 1) : (NUM_OCTYPES-1)); k >= 0; k--) {
|
||||||
if (strcmp(audio_config_p->achan[ch].octrl[ot].ptt_device,audio_config_p->achan[j].octrl[k].ptt_device) == 0) {
|
if (strcmp(audio_config_p->achan[ch].octrl[ot].ptt_device,audio_config_p->achan[j].octrl[k].ptt_device) == 0) {
|
||||||
fd = ptt_fd[j][k];
|
fd = ptt_fd[j][k];
|
||||||
|
@ -963,7 +963,7 @@ void ptt_init (struct audio_s *audio_config_p)
|
||||||
|
|
||||||
#ifdef USE_HAMLIB
|
#ifdef USE_HAMLIB
|
||||||
for (ch = 0; ch < MAX_CHANS; ch++) {
|
for (ch = 0; ch < MAX_CHANS; ch++) {
|
||||||
if (save_audio_config_p->achan[ch].valid) {
|
if (save_audio_config_p->achan[ch].medium == MEDIUM_RADIO) {
|
||||||
int ot;
|
int ot;
|
||||||
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
||||||
if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_HAMLIB) {
|
if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_HAMLIB) {
|
||||||
|
@ -1030,7 +1030,7 @@ void ptt_init (struct audio_s *audio_config_p)
|
||||||
|
|
||||||
for (ch = 0; ch < MAX_CHANS; ch++) {
|
for (ch = 0; ch < MAX_CHANS; ch++) {
|
||||||
|
|
||||||
if (audio_config_p->achan[ch].valid) {
|
if (audio_config_p->achan[ch].medium == MEDIUM_RADIO) {
|
||||||
int ot;
|
int ot;
|
||||||
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
||||||
if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_CM108) {
|
if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_CM108) {
|
||||||
|
@ -1051,7 +1051,7 @@ void ptt_init (struct audio_s *audio_config_p)
|
||||||
/* Why doesn't it transmit? Probably forgot to specify PTT option. */
|
/* Why doesn't it transmit? Probably forgot to specify PTT option. */
|
||||||
|
|
||||||
for (ch=0; ch<MAX_CHANS; ch++) {
|
for (ch=0; ch<MAX_CHANS; ch++) {
|
||||||
if (audio_config_p->achan[ch].valid) {
|
if (audio_config_p->achan[ch].medium == MEDIUM_RADIO) {
|
||||||
if(audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_method == PTT_METHOD_NONE) {
|
if(audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_method == PTT_METHOD_NONE) {
|
||||||
text_color_set(DW_COLOR_INFO);
|
text_color_set(DW_COLOR_INFO);
|
||||||
dw_printf ("Note: PTT not configured for channel %d. (Ignore this if using VOX.)\n", ch);
|
dw_printf ("Note: PTT not configured for channel %d. (Ignore this if using VOX.)\n", ch);
|
||||||
|
@ -1103,7 +1103,7 @@ void ptt_set (int ot, int chan, int ptt_signal)
|
||||||
|
|
||||||
assert (chan >= 0 && chan < MAX_CHANS);
|
assert (chan >= 0 && chan < MAX_CHANS);
|
||||||
|
|
||||||
if ( ! save_audio_config_p->achan[chan].valid) {
|
if ( save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Internal error, ptt_set ( %s, %d, %d ), did not expect invalid channel.\n", otnames[ot], chan, ptt);
|
dw_printf ("Internal error, ptt_set ( %s, %d, %d ), did not expect invalid channel.\n", otnames[ot], chan, ptt);
|
||||||
return;
|
return;
|
||||||
|
@ -1314,7 +1314,7 @@ int get_input (int it, int chan)
|
||||||
assert (it >= 0 && it < NUM_ICTYPES);
|
assert (it >= 0 && it < NUM_ICTYPES);
|
||||||
assert (chan >= 0 && chan < MAX_CHANS);
|
assert (chan >= 0 && chan < MAX_CHANS);
|
||||||
|
|
||||||
if ( ! save_audio_config_p->achan[chan].valid) {
|
if ( save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Internal error, get_input ( %d, %d ), did not expect invalid channel.\n", it, chan);
|
dw_printf ("Internal error, get_input ( %d, %d ), did not expect invalid channel.\n", it, chan);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1378,7 +1378,7 @@ void ptt_term (void)
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
for (n = 0; n < MAX_CHANS; n++) {
|
for (n = 0; n < MAX_CHANS; n++) {
|
||||||
if (save_audio_config_p->achan[n].valid) {
|
if (save_audio_config_p->achan[n].medium == MEDIUM_RADIO) {
|
||||||
int ot;
|
int ot;
|
||||||
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
||||||
ptt_set (ot, n, 0);
|
ptt_set (ot, n, 0);
|
||||||
|
@ -1387,7 +1387,7 @@ void ptt_term (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n = 0; n < MAX_CHANS; n++) {
|
for (n = 0; n < MAX_CHANS; n++) {
|
||||||
if (save_audio_config_p->achan[n].valid) {
|
if (save_audio_config_p->achan[n].medium == MEDIUM_RADIO) {
|
||||||
int ot;
|
int ot;
|
||||||
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
||||||
if (ptt_fd[n][ot] != INVALID_HANDLE_VALUE) {
|
if (ptt_fd[n][ot] != INVALID_HANDLE_VALUE) {
|
||||||
|
@ -1405,7 +1405,7 @@ void ptt_term (void)
|
||||||
#ifdef USE_HAMLIB
|
#ifdef USE_HAMLIB
|
||||||
|
|
||||||
for (n = 0; n < MAX_CHANS; n++) {
|
for (n = 0; n < MAX_CHANS; n++) {
|
||||||
if (save_audio_config_p->achan[n].valid) {
|
if (save_audio_config_p->achan[n].medium == MEDIUM_RADIO) {
|
||||||
int ot;
|
int ot;
|
||||||
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
for (ot = 0; ot < NUM_OCTYPES; ot++) {
|
||||||
if (rig[n][ot] != NULL) {
|
if (rig[n][ot] != NULL) {
|
||||||
|
@ -1444,14 +1444,14 @@ int main ()
|
||||||
|
|
||||||
my_audio_config.adev[0].num_channels = 2;
|
my_audio_config.adev[0].num_channels = 2;
|
||||||
|
|
||||||
my_audio_config.achan[0].valid = 1;
|
my_audio_config.achan[0].medium = MEDIUM_RADIO;
|
||||||
my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_method = PTT_METHOD_SERIAL;
|
my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_method = PTT_METHOD_SERIAL;
|
||||||
// TODO: device should be command line argument.
|
// TODO: device should be command line argument.
|
||||||
strlcpy (my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_device, "COM3", sizeof(my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_device));
|
strlcpy (my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_device, "COM3", sizeof(my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_device));
|
||||||
//strlcpy (my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_device, "/dev/ttyUSB0", sizeof(my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_device));
|
//strlcpy (my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_device, "/dev/ttyUSB0", sizeof(my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_device));
|
||||||
my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_line = PTT_LINE_RTS;
|
my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_line = PTT_LINE_RTS;
|
||||||
|
|
||||||
my_audio_config.achan[1].valid = 1;
|
my_audio_config.achan[1].medium = MEDIUM_RADIO;
|
||||||
my_audio_config.achan[1].octrl[OCTYPE_PTT].ptt_method = PTT_METHOD_SERIAL;
|
my_audio_config.achan[1].octrl[OCTYPE_PTT].ptt_method = PTT_METHOD_SERIAL;
|
||||||
strlcpy (my_audio_config.achan[1].octrl[OCTYPE_PTT].ptt_device, "COM3", sizeof(my_audio_config.achan[1].octrl[OCTYPE_PTT].ptt_device));
|
strlcpy (my_audio_config.achan[1].octrl[OCTYPE_PTT].ptt_device, "COM3", sizeof(my_audio_config.achan[1].octrl[OCTYPE_PTT].ptt_device));
|
||||||
//strlcpy (my_audio_config.achan[1].octrl[OCTYPE_PTT].ptt_device, "/dev/ttyUSB0", sizeof(my_audio_config.achan[1].octrl[OCTYPE_PTT].ptt_device));
|
//strlcpy (my_audio_config.achan[1].octrl[OCTYPE_PTT].ptt_device, "/dev/ttyUSB0", sizeof(my_audio_config.achan[1].octrl[OCTYPE_PTT].ptt_device));
|
||||||
|
@ -1525,7 +1525,7 @@ int main ()
|
||||||
|
|
||||||
memset (&my_audio_config, 0, sizeof(my_audio_config));
|
memset (&my_audio_config, 0, sizeof(my_audio_config));
|
||||||
my_audio_config.adev[0].num_channels = 1;
|
my_audio_config.adev[0].num_channels = 1;
|
||||||
my_audio_config.valid[0] = 1;
|
my_audio_config.achan[0].medium = MEDIUM_RADIO;
|
||||||
my_audio_config.adev[0].octrl[OCTYPE_PTT].ptt_method = PTT_METHOD_GPIO;
|
my_audio_config.adev[0].octrl[OCTYPE_PTT].ptt_method = PTT_METHOD_GPIO;
|
||||||
my_audio_config.adev[0].octrl[OCTYPE_PTT].out_gpio_num = 25;
|
my_audio_config.adev[0].octrl[OCTYPE_PTT].out_gpio_num = 25;
|
||||||
|
|
||||||
|
@ -1556,10 +1556,10 @@ int main ()
|
||||||
#if 0
|
#if 0
|
||||||
memset (&my_audio_config, 0, sizeof(my_audio_config));
|
memset (&my_audio_config, 0, sizeof(my_audio_config));
|
||||||
my_audio_config.num_channels = 2;
|
my_audio_config.num_channels = 2;
|
||||||
my_audio_config.valid[0] = 1;
|
my_audio_config.achan[0].medium = MEDIUM_RADIO;
|
||||||
my_audio_config.adev[0].octrl[OCTYPE_PTT].ptt_method = PTT_METHOD_LPT;
|
my_audio_config.adev[0].octrl[OCTYPE_PTT].ptt_method = PTT_METHOD_LPT;
|
||||||
my_audio_config.adev[0].octrl[OCTYPE_PTT].ptt_lpt_bit = 0;
|
my_audio_config.adev[0].octrl[OCTYPE_PTT].ptt_lpt_bit = 0;
|
||||||
my_audio_config.valid[1] = 1;
|
my_audio_config.achan[1].medium = MEDIUM_RADIO;
|
||||||
my_audio_config.adev[1].octrl[OCTYPE_PTT].ptt_method = PTT_METHOD_LPT;
|
my_audio_config.adev[1].octrl[OCTYPE_PTT].ptt_method = PTT_METHOD_LPT;
|
||||||
my_audio_config.adev[1].octrl[OCTYPE_PTT].ptt_lpt_bit = 1;
|
my_audio_config.adev[1].octrl[OCTYPE_PTT].ptt_lpt_bit = 1;
|
||||||
|
|
||||||
|
|
55
server.c
55
server.c
|
@ -1422,19 +1422,24 @@ static THREAD_F cmd_listen_thread (void *arg)
|
||||||
// We can have gaps in the numbering.
|
// We can have gaps in the numbering.
|
||||||
// I wonder what applications will think about that.
|
// I wonder what applications will think about that.
|
||||||
|
|
||||||
#if 1
|
|
||||||
// No other place cares about total number.
|
// No other place cares about total number.
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
for (j=0; j<MAX_CHANS; j++) {
|
for (j=0; j<MAX_CHANS; j++) {
|
||||||
if (save_audio_config_p->achan[j].valid) {
|
if (save_audio_config_p->achan[j].medium == MEDIUM_RADIO ||
|
||||||
|
save_audio_config_p->achan[j].medium == MEDIUM_IGATE ||
|
||||||
|
save_audio_config_p->achan[j].medium == MEDIUM_NETTNC) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf (reply.info, sizeof(reply.info), "%d;", count);
|
snprintf (reply.info, sizeof(reply.info), "%d;", count);
|
||||||
|
|
||||||
for (j=0; j<MAX_CHANS; j++) {
|
for (j=0; j<MAX_CHANS; j++) {
|
||||||
if (save_audio_config_p->achan[j].valid) {
|
|
||||||
|
switch (save_audio_config_p->achan[j].medium) {
|
||||||
|
|
||||||
|
case MEDIUM_RADIO:
|
||||||
|
{
|
||||||
char stemp[100];
|
char stemp[100];
|
||||||
int a = ACHAN2ADEV(j);
|
int a = ACHAN2ADEV(j);
|
||||||
// If I was really ambitious, some description could be provided.
|
// If I was really ambitious, some description could be provided.
|
||||||
|
@ -1449,20 +1454,40 @@ static THREAD_F cmd_listen_thread (void *arg)
|
||||||
strlcat (reply.info, stemp, sizeof(reply.info));
|
strlcat (reply.info, stemp, sizeof(reply.info));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
#else
|
case MEDIUM_IGATE:
|
||||||
if (num_channels == 1) {
|
{
|
||||||
snprintf (reply.info, sizeof(reply.info), "1;Port1 Single channel;");
|
char stemp[100];
|
||||||
|
snprintf (stemp, sizeof(stemp), "Port%d Internet Gateway;", j+1);
|
||||||
|
strlcat (reply.info, stemp, sizeof(reply.info));
|
||||||
}
|
}
|
||||||
else {
|
break;
|
||||||
snprintf (reply.info, sizeof(reply.info), "2;Port1 Left channel;Port2 Right Channel;");
|
|
||||||
|
case MEDIUM_NETTNC:
|
||||||
|
{
|
||||||
|
// could elaborate with hostname, etc.
|
||||||
|
char stemp[100];
|
||||||
|
snprintf (stemp, sizeof(stemp), "Port%d Network TNC;", j+1);
|
||||||
|
strlcat (reply.info, stemp, sizeof(reply.info));
|
||||||
}
|
}
|
||||||
#endif
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// could elaborate with hostname, etc.
|
||||||
|
char stemp[100];
|
||||||
|
snprintf (stemp, sizeof(stemp), "Port%d INVALID CHANNEL;", j+1);
|
||||||
|
strlcat (reply.info, stemp, sizeof(reply.info));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
} // switch
|
||||||
|
} // for each channel
|
||||||
|
|
||||||
reply.hdr.data_len_NETLE = host2netle(strlen(reply.info) + 1);
|
reply.hdr.data_len_NETLE = host2netle(strlen(reply.info) + 1);
|
||||||
|
|
||||||
send_to_client (client, &reply);
|
send_to_client (client, &reply);
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1688,7 +1713,9 @@ static THREAD_F cmd_listen_thread (void *arg)
|
||||||
|
|
||||||
int chan = cmd.hdr.portx;
|
int chan = cmd.hdr.portx;
|
||||||
|
|
||||||
if (chan >= 0 && chan < MAX_CHANS && save_audio_config_p->achan[chan].valid) {
|
// Connected mode can only be used with internal modems.
|
||||||
|
|
||||||
|
if (chan >= 0 && chan < MAX_CHANS && save_audio_config_p->achan[chan].medium == MEDIUM_RADIO) {
|
||||||
ok = 1;
|
ok = 1;
|
||||||
dlq_register_callsign (cmd.hdr.call_from, chan, client);
|
dlq_register_callsign (cmd.hdr.call_from, chan, client);
|
||||||
}
|
}
|
||||||
|
@ -1715,7 +1742,9 @@ static THREAD_F cmd_listen_thread (void *arg)
|
||||||
|
|
||||||
int chan = cmd.hdr.portx;
|
int chan = cmd.hdr.portx;
|
||||||
|
|
||||||
if (chan >= 0 && chan < MAX_CHANS && save_audio_config_p->achan[chan].valid) {
|
// Connected mode can only be used with internal modems.
|
||||||
|
|
||||||
|
if (chan >= 0 && chan < MAX_CHANS && save_audio_config_p->achan[chan].medium == MEDIUM_RADIO) {
|
||||||
dlq_unregister_callsign (cmd.hdr.call_from, chan, client);
|
dlq_unregister_callsign (cmd.hdr.call_from, chan, client);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
25
tq.c
25
tq.c
|
@ -148,7 +148,7 @@ void tq_init (struct audio_s *audio_config_p)
|
||||||
|
|
||||||
for (c = 0; c < MAX_CHANS; c++) {
|
for (c = 0; c < MAX_CHANS; c++) {
|
||||||
|
|
||||||
if (audio_config_p->achan[c].valid) {
|
if (audio_config_p->achan[c].medium == MEDIUM_RADIO) {
|
||||||
|
|
||||||
wake_up_event[c] = CreateEvent (NULL, 0, 0, NULL);
|
wake_up_event[c] = CreateEvent (NULL, 0, 0, NULL);
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ void tq_init (struct audio_s *audio_config_p)
|
||||||
|
|
||||||
xmit_thread_is_waiting[c] = 0;
|
xmit_thread_is_waiting[c] = 0;
|
||||||
|
|
||||||
if (audio_config_p->achan[c].valid) {
|
if (audio_config_p->achan[c].medium == MEDIUM_RADIO) {
|
||||||
err = pthread_cond_init (&(wake_up_cond[c]), NULL);
|
err = pthread_cond_init (&(wake_up_cond[c]), NULL);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
@ -247,11 +247,15 @@ void tq_append (int chan, int prio, packet_t pp)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (chan < 0 || chan >= MAX_CHANS || ! save_audio_config_p->achan[chan].valid) {
|
if (chan < 0 || chan >= MAX_CHANS || save_audio_config_p->achan[chan].medium == MEDIUM_NONE) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("ERROR - Request to transmit on invalid radio channel %d.\n", chan);
|
dw_printf ("ERROR - Request to transmit on invalid radio channel %d.\n", chan);
|
||||||
dw_printf ("This is probably a client application error, not a problem with direwolf.\n");
|
dw_printf ("This is probably a client application error, not a problem with direwolf.\n");
|
||||||
dw_printf ("AX.25 for Linux is known to transmit on channels 2 & 8 sometimes when it shouldn't.\n");
|
dw_printf ("Are you using AX.25 for Linux? It might be trying to use a modified\n");
|
||||||
|
dw_printf ("version of KISS which uses the port field differently than the\n");
|
||||||
|
dw_printf ("original KISS protocol specification. The solution might be to use\n");
|
||||||
|
dw_printf ("a command like \"kissparms -c 1 -p radio\" to set CRC none mode.\n");
|
||||||
|
dw_printf ("\n");
|
||||||
ax25_delete(pp);
|
ax25_delete(pp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -447,9 +451,13 @@ void lm_data_request (int chan, int prio, packet_t pp)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (chan < 0 || chan >= MAX_CHANS || ! save_audio_config_p->achan[chan].valid) {
|
if (chan < 0 || chan >= MAX_CHANS || save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) {
|
||||||
|
// Connected mode is allowed only with internal modems.
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("ERROR - Request to transmit on invalid radio channel %d.\n", chan);
|
dw_printf ("ERROR - Request to transmit on invalid radio channel %d.\n", chan);
|
||||||
|
dw_printf ("Connected packet mode is allowed only with internal modems.\n");
|
||||||
|
dw_printf ("Why aren't external KISS modems allowed? See\n");
|
||||||
|
dw_printf ("Why-is-9600-only-twice-as-fast-as-1200.pdf for explanation.\n");
|
||||||
ax25_delete(pp);
|
ax25_delete(pp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -600,9 +608,14 @@ void lm_seize_request (int chan)
|
||||||
dw_printf ("lm_seize_request (chan=%d)\n", chan);
|
dw_printf ("lm_seize_request (chan=%d)\n", chan);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (chan < 0 || chan >= MAX_CHANS || ! save_audio_config_p->achan[chan].valid) {
|
|
||||||
|
if (chan < 0 || chan >= MAX_CHANS || save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) {
|
||||||
|
// Connected mode is allowed only with internal modems.
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("ERROR - Request to transmit on invalid radio channel %d.\n", chan);
|
dw_printf ("ERROR - Request to transmit on invalid radio channel %d.\n", chan);
|
||||||
|
dw_printf ("Connected packet mode is allowed only with internal modems.\n");
|
||||||
|
dw_printf ("Why aren't external KISS modems allowed? See\n");
|
||||||
|
dw_printf ("Why-is-9600-only-twice-as-fast-as-1200.pdf for explanation.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
xmit.c
3
xmit.c
|
@ -277,8 +277,7 @@ void xmit_init (struct audio_s *p_modem, int debug_xmit_packet)
|
||||||
|
|
||||||
for (j=0; j<MAX_CHANS; j++) {
|
for (j=0; j<MAX_CHANS; j++) {
|
||||||
|
|
||||||
if (p_modem->achan[j].valid) {
|
if (p_modem->achan[j].medium == MEDIUM_RADIO) {
|
||||||
|
|
||||||
#if __WIN32__
|
#if __WIN32__
|
||||||
xmit_th[j] = (HANDLE)_beginthreadex (NULL, 0, xmit_thread, (void*)(long)j, 0, NULL);
|
xmit_th[j] = (HANDLE)_beginthreadex (NULL, 0, xmit_thread, (void*)(long)j, 0, NULL);
|
||||||
if (xmit_th[j] == NULL) {
|
if (xmit_th[j] == NULL) {
|
||||||
|
|
Loading…
Reference in New Issue