From 45cd680b904c8b4b535afa675afa8b3b8e7a12dc Mon Sep 17 00:00:00 2001 From: wb2osz Date: Thu, 9 Dec 2021 22:30:31 -0500 Subject: [PATCH] First rough approximation of ICHANNEL. --- src/atest.c | 4 +- src/audio.h | 29 ++++++++----- src/ax25_pad.c | 7 +++ src/beacon.c | 4 +- src/cdigipeater.c | 2 +- src/config.c | 108 +++++++++++++++++++++++++++++++--------------- src/demod.c | 17 +++++++- src/digipeater.c | 4 +- src/direwolf.c | 35 +++++++++++---- src/direwolf.h | 10 ++++- src/dlq.c | 2 +- src/dtmf.c | 2 +- src/gen_packets.c | 4 +- src/gen_tone.c | 4 +- src/hdlc_rec.c | 2 +- src/igate.c | 63 ++++++++++++++++++++++++++- src/kiss_frame.c | 2 +- src/morse.c | 6 +-- src/multi_modem.c | 2 +- src/ptt.c | 38 ++++++++-------- src/server.c | 12 +++--- src/tq.c | 10 ++--- src/xmit.c | 2 +- 23 files changed, 262 insertions(+), 107 deletions(-) diff --git a/src/atest.c b/src/atest.c index caea4bc..910eecd 100644 --- a/src/atest.c +++ b/src/atest.c @@ -620,9 +620,9 @@ int main (int argc, char *argv[]) my_audio_config.adev[0].bits_per_sample = format.wbitspersample; my_audio_config.adev[0].num_channels = format.nchannels; - my_audio_config.achan[0].medium = MEDIUM_RADIO; + my_audio_config.chan_medium[0] = MEDIUM_RADIO; if (format.nchannels == 2) { - my_audio_config.achan[1].medium = MEDIUM_RADIO; + my_audio_config.chan_medium[1] = MEDIUM_RADIO; } text_color_set(DW_COLOR_INFO); diff --git a/src/audio.h b/src/audio.h index f112f76..78327a7 100644 --- a/src/audio.h +++ b/src/audio.h @@ -119,32 +119,39 @@ struct audio_s { /* I put it here, rather than with the rest of the link layer */ /* parameters because it is really a part of the HDLC layer */ /* and is part of the KISS TNC functionality rather than our data link layer. */ + /* Future: not used yet. */ + char timestamp_format[40]; /* -T option */ /* Precede received & transmitted frames with timestamp. */ /* Command line option uses "strftime" format string. */ - /* Properties for each channel, common to receive and transmit. */ - /* 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. */ + // Properties for all channels. + + enum medium_e chan_medium[MAX_TOTAL_CHANS]; + // MEDIUM_NONE for invalid. + // MEDIUM_RADIO for internal modem. (only possibility earlier) + // MEDIUM_IGATE allows application access to IGate. + // MEDIUM_NETTNC for external TNC via TCP. + + int igate_vchannel; /* Virtual channel mapped to APRS-IS. */ + /* -1 for none. */ + /* Redundant but it makes things quicker and simpler */ + /* than always searching thru above. */ + + /* Properties for each radio channel, common to receive and transmit. */ + /* Can be different for each radio channel. */ struct achan_param_s { - // 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. - - + // What else should be moved out of structure and enlarged when NETTNC is implemented. ??? char mycall[AX25_MAX_ADDR_LEN]; /* Call associated with this radio channel. */ /* Could all be the same or different. */ diff --git a/src/ax25_pad.c b/src/ax25_pad.c index fe9368e..de49c08 100644 --- a/src/ax25_pad.c +++ b/src/ax25_pad.c @@ -511,6 +511,13 @@ packet_t ax25_from_text (char *monitor, int strict) // printf ("DEBUG: get digi loop, num addr = %d, address = '%s'\n", k, pa);// FIXME + // Hack for q construct, from APRS-IS, so it does not cause panic later. + + if ( ! strict && pa[0] == 'q' && pa[1] == 'A') { + pa[0] = 'Q'; + pa[2] = toupper(pa[2]); + } + if ( ! ax25_parse_addr (k, pa, strict, atemp, &ssid_temp, &heard_temp)) { text_color_set(DW_COLOR_ERROR); dw_printf ("Failed to create packet from text. Bad digipeater address\n"); diff --git a/src/beacon.c b/src/beacon.c index a10355f..70e3bed 100644 --- a/src/beacon.c +++ b/src/beacon.c @@ -163,8 +163,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 (g_modem_config_p->achan[chan].medium == MEDIUM_RADIO || - g_modem_config_p->achan[chan].medium == MEDIUM_NETTNC) { + if (g_modem_config_p->chan_medium[chan] == MEDIUM_RADIO || + g_modem_config_p->chan_medium[chan] == MEDIUM_NETTNC) { if (strlen(g_modem_config_p->achan[chan].mycall) > 0 && strcasecmp(g_modem_config_p->achan[chan].mycall, "N0CALL") != 0 && diff --git a/src/cdigipeater.c b/src/cdigipeater.c index b126b83..06128b2 100644 --- a/src/cdigipeater.c +++ b/src/cdigipeater.c @@ -132,7 +132,7 @@ void cdigipeater (int from_chan, packet_t pp) // 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].medium != MEDIUM_RADIO) { + if ( from_chan < 0 || from_chan >= MAX_CHANS || save_audio_config_p->chan_medium[from_chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("cdigipeater: Did not expect to receive on invalid channel %d.\n", from_chan); return; diff --git a/src/config.c b/src/config.c index 730991c..b6de631 100644 --- a/src/config.c +++ b/src/config.c @@ -736,6 +736,8 @@ void config_init (char *fname, struct audio_s *p_audio_config, memset (p_audio_config, 0, sizeof(struct audio_s)); + p_audio_config->igate_vchannel = -1; // none. + /* First audio device is always available with defaults. */ /* Others must be explicitly defined before use. */ @@ -755,7 +757,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, for (channel=0; channelachan[channel].medium = MEDIUM_NONE; /* One or both channels will be */ + p_audio_config->chan_medium[channel] = MEDIUM_NONE; /* One or both channels will be */ /* set to radio when corresponding */ /* audio device is defined. */ p_audio_config->achan[channel].modem_type = MODEM_AFSK; @@ -808,7 +810,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, /* First channel should always be valid. */ /* If there is no ADEVICE, it uses default device in mono. */ - p_audio_config->achan[0].medium = MEDIUM_RADIO; + p_audio_config->chan_medium[0] = MEDIUM_RADIO; memset (p_digi_config, 0, sizeof(struct digi_config_s)); // APRS digipeater p_digi_config->dedupe_time = DEFAULT_DEDUPE; @@ -1031,7 +1033,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, p_audio_config->adev[adevice].defined = 1; /* First channel of device is valid. */ - p_audio_config->achan[ADEVFIRSTCHAN(adevice)].medium = MEDIUM_RADIO; + p_audio_config->chan_medium[ADEVFIRSTCHAN(adevice)] = 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_out, t, sizeof(p_audio_config->adev[adevice].adevice_out)); @@ -1086,7 +1088,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, p_audio_config->adev[adevice].defined = 1; /* First channel of device is valid. */ - p_audio_config->achan[ADEVFIRSTCHAN(adevice)].medium = MEDIUM_RADIO; + p_audio_config->chan_medium[ADEVFIRSTCHAN(adevice)] = MEDIUM_RADIO; strlcpy (p_audio_config->adev[adevice].adevice_in, t, sizeof(p_audio_config->adev[adevice].adevice_in)); } @@ -1113,7 +1115,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, p_audio_config->adev[adevice].defined = 1; /* First channel of device is valid. */ - p_audio_config->achan[ADEVFIRSTCHAN(adevice)].medium = MEDIUM_RADIO; + p_audio_config->chan_medium[ADEVFIRSTCHAN(adevice)] = MEDIUM_RADIO; strlcpy (p_audio_config->adev[adevice].adevice_out, t, sizeof(p_audio_config->adev[adevice].adevice_out)); } @@ -1160,9 +1162,9 @@ void config_init (char *fname, struct audio_s *p_audio_config, /* Set valid channels depending on mono or stereo. */ - p_audio_config->achan[ADEVFIRSTCHAN(adevice)].medium = MEDIUM_RADIO; + p_audio_config->chan_medium[ADEVFIRSTCHAN(adevice)] = MEDIUM_RADIO; if (n == 2) { - p_audio_config->achan[ADEVFIRSTCHAN(adevice) + 1].medium = MEDIUM_RADIO; + p_audio_config->chan_medium[ADEVFIRSTCHAN(adevice) + 1] = MEDIUM_RADIO; } } else { @@ -1176,7 +1178,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, */ /* - * CHANNEL - Set channel for following commands. + * CHANNEL n - Set channel for channel-specific commands. */ else if (strcasecmp(t, "CHANNEL") == 0) { @@ -1192,7 +1194,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, channel = n; - if (p_audio_config->achan[n].medium != MEDIUM_RADIO) { + if (p_audio_config->chan_medium[n] != MEDIUM_RADIO) { if ( ! p_audio_config->adev[ACHAN2ADEV(n)].defined) { text_color_set(DW_COLOR_ERROR); @@ -1212,6 +1214,44 @@ void config_init (char *fname, struct audio_s *p_audio_config, } } +/* + * ICHANNEL n - Define IGate virtual channel. + * + * This allows a client application to talk to to APRS-IS + * by using a channel number outside the normal range for modems. + * In the future there might be other typs of virtual channels. + * This does not change the current channel number used by MODEM, PTT, etc. + */ + + else if (strcasecmp(t, "ICHANNEL") == 0) { + t = split(NULL,0); + if (t == NULL) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Line %d: Missing virtual channel number for ICHANNEL command.\n", line); + continue; + } + int ichan = atoi(t); + if (ichan >= MAX_CHANS && ichan < MAX_TOTAL_CHANS) { + + if (p_audio_config->chan_medium[ichan] == MEDIUM_NONE) { + + p_audio_config->chan_medium[ichan] = MEDIUM_IGATE; + + // This is redundant but saves the time of searching through all + // the channels for each packet. + p_audio_config->igate_vchannel = ichan; + } + else { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Line %d: ICHANNEL can't use %d because it is already in use.\n", line, ichan); + } + } + else { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Line %d: ICHANNEL number must in range of %d to %d.\n", line, MAX_CHANS, MAX_TOTAL_CHANS-1); + } + } + /* * MYCALL station */ @@ -2388,8 +2428,8 @@ void config_init (char *fname, struct audio_s *p_audio_config, // 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) { + if (p_audio_config->chan_medium[from_chan] != MEDIUM_RADIO && + p_audio_config->chan_medium[from_chan] != MEDIUM_NETTNC) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n", line, from_chan); @@ -2416,8 +2456,8 @@ void config_init (char *fname, struct audio_s *p_audio_config, continue; } - if (p_audio_config->achan[to_chan].medium != MEDIUM_RADIO && - p_audio_config->achan[to_chan].medium != MEDIUM_NETTNC) { + if (p_audio_config->chan_medium[to_chan] != MEDIUM_RADIO && + p_audio_config->chan_medium[to_chan] != MEDIUM_NETTNC) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: TO-channel %d is not valid.\n", line, to_chan); @@ -2545,7 +2585,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, // Only radio channels are valid for regenerate. - if (p_audio_config->achan[from_chan].medium != MEDIUM_RADIO) { + if (p_audio_config->chan_medium[from_chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n", line, from_chan); @@ -2571,7 +2611,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, MAX_CHANS-1, line); continue; } - if (p_audio_config->achan[to_chan].medium != MEDIUM_RADIO) { + if (p_audio_config->chan_medium[to_chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: TO-channel %d is not valid.\n", line, to_chan); @@ -2622,7 +2662,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, // 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) { + if (p_audio_config->chan_medium[from_chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n", line, from_chan); @@ -2649,7 +2689,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, MAX_CHANS-1, line); continue; } - if (p_audio_config->achan[to_chan].medium != MEDIUM_RADIO) { + if (p_audio_config->chan_medium[to_chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: TO-channel %d is not valid.\n", line, to_chan); @@ -2740,14 +2780,14 @@ void config_init (char *fname, struct audio_s *p_audio_config, continue; } - if (p_audio_config->achan[from_chan].medium != MEDIUM_RADIO && - p_audio_config->achan[from_chan].medium != MEDIUM_NETTNC) { + if (p_audio_config->chan_medium[from_chan] != MEDIUM_RADIO && + p_audio_config->chan_medium[from_chan] != MEDIUM_NETTNC) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n", line, from_chan); continue; } - if (p_audio_config->achan[from_chan].medium == MEDIUM_IGATE) { + if (p_audio_config->chan_medium[from_chan] == 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); @@ -2772,14 +2812,14 @@ void config_init (char *fname, struct audio_s *p_audio_config, MAX_CHANS-1, line); continue; } - if (p_audio_config->achan[to_chan].medium != MEDIUM_RADIO && - p_audio_config->achan[to_chan].medium != MEDIUM_NETTNC) { + if (p_audio_config->chan_medium[to_chan] != MEDIUM_RADIO && + p_audio_config->chan_medium[to_chan] != MEDIUM_NETTNC) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: TO-channel %d is not valid.\n", line, to_chan); continue; } - if (p_audio_config->achan[to_chan].medium == MEDIUM_IGATE) { + if (p_audio_config->chan_medium[to_chan] == 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); @@ -2838,7 +2878,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, // 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) { + if (p_audio_config->chan_medium[from_chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: FROM-channel %d is not valid.\n", line, from_chan); @@ -2859,7 +2899,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, MAX_CHANS-1, line); continue; } - if (p_audio_config->achan[to_chan].medium != MEDIUM_RADIO) { + if (p_audio_config->chan_medium[to_chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: TO-channel %d is not valid.\n", line, to_chan); @@ -4020,7 +4060,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, // 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) { + if (p_audio_config->chan_medium[r] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: TTOBJ DTMF receive channel %d is not valid.\n", line, r); @@ -4046,8 +4086,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); x = -1; } - else if (p_audio_config->achan[x].medium != MEDIUM_RADIO && - p_audio_config->achan[x].medium != MEDIUM_NETTNC) { + else if (p_audio_config->chan_medium[x] != MEDIUM_RADIO && + p_audio_config->chan_medium[x] != MEDIUM_NETTNC) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: TTOBJ transmit channel %d is not valid.\n", line, x); x = -1; @@ -5366,7 +5406,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, /* 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)) { + (p_audio_config->chan_medium[i] == MEDIUM_RADIO || p_audio_config->chan_medium[i] == MEDIUM_NETTNC)) { 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); @@ -5392,7 +5432,7 @@ void config_init (char *fname, struct audio_s *p_audio_config, if (strlen(p_igate_config->t2_login) > 0) { for (j=0; jachan[j].medium == MEDIUM_RADIO || p_audio_config->achan[j].medium == MEDIUM_NETTNC) { + if (p_audio_config->chan_medium[j] == MEDIUM_RADIO || p_audio_config->chan_medium[j] == MEDIUM_NETTNC) { if (p_digi_config->filter_str[MAX_CHANS][j] == NULL) { p_digi_config->filter_str[MAX_CHANS][j] = strdup("i/60"); } @@ -5485,7 +5525,7 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_ } else if (value[0] == 'r' || value[0] == 'R') { int n = atoi(value+1); - if ( n < 0 || n >= MAX_CHANS || p_audio_config->achan[n].medium == MEDIUM_NONE) { + if ( n < 0 || n >= MAX_CHANS || p_audio_config->chan_medium[n] == MEDIUM_NONE) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: Simulated receive on channel %d is not valid.\n", line, n); continue; @@ -5495,7 +5535,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') { int n = atoi(value+1); - if ( n < 0 || n >= MAX_CHANS || p_audio_config->achan[n].medium == MEDIUM_NONE) { + if ( n < 0 || n >= MAX_CHANS || p_audio_config->chan_medium[n] == MEDIUM_NONE) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: Send to channel %d is not valid.\n", line, n); continue; @@ -5506,7 +5546,7 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_ } else { int n = atoi(value); - if ( n < 0 || n >= MAX_CHANS || p_audio_config->achan[n].medium == MEDIUM_NONE) { + if ( n < 0 || n >= MAX_CHANS || p_audio_config->chan_medium[n] == MEDIUM_NONE) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: Send to channel %d is not valid.\n", line, n); continue; @@ -5729,7 +5769,7 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_ if (b->sendto_type == SENDTO_XMIT) { - if ( b->sendto_chan < 0 || b->sendto_chan >= MAX_CHANS || p_audio_config->achan[b->sendto_chan].medium == MEDIUM_NONE) { + if ( b->sendto_chan < 0 || b->sendto_chan >= MAX_CHANS || p_audio_config->chan_medium[b->sendto_chan] == MEDIUM_NONE) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: Send to channel %d is not valid.\n", line, b->sendto_chan); return (0); diff --git a/src/demod.c b/src/demod.c index 982d08a..482c107 100644 --- a/src/demod.c +++ b/src/demod.c @@ -102,7 +102,7 @@ int demod_init (struct audio_s *pa) for (chan = 0; chan < MAX_CHANS; chan++) { - if (save_audio_config_p->achan[chan].medium == MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[chan] == MEDIUM_RADIO) { char *p; char just_letters[16]; @@ -804,10 +804,23 @@ int demod_init (struct audio_s *pa) } /* switch on modulation type. */ - } /* if channel number is valid */ + } /* if channel medium is radio */ + +// FIXME dw_printf ("-------- end of loop for chn %d \n", chan); } /* for chan ... */ + // Now the virtual channels. FIXME: could be single loop. + + for (chan = MAX_CHANS; chan < MAX_TOTAL_CHANS; chan++) { + +// FIXME dw_printf ("-------- virtual channel loop %d \n", chan); + + if (chan == save_audio_config_p->igate_vchannel) { + text_color_set(DW_COLOR_DEBUG); + dw_printf ("Channel %d: IGate virtual channel.\n", chan); + } + } return (0); diff --git a/src/digipeater.c b/src/digipeater.c index 75aa53d..3c6a6bc 100644 --- a/src/digipeater.c +++ b/src/digipeater.c @@ -154,8 +154,8 @@ void digipeater (int from_chan, packet_t pp) // 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)) { + (save_audio_config_p->chan_medium[from_chan] != MEDIUM_RADIO && + save_audio_config_p->chan_medium[from_chan] != MEDIUM_NETTNC)) { text_color_set(DW_COLOR_ERROR); dw_printf ("APRS digipeater: Did not expect to receive on invalid channel %d.\n", from_chan); } diff --git a/src/direwolf.c b/src/direwolf.c index 76247f5..1228612 100644 --- a/src/direwolf.c +++ b/src/direwolf.c @@ -299,7 +299,7 @@ int main (int argc, char *argv[]) text_color_init(t_opt); text_color_set(DW_COLOR_INFO); //dw_printf ("Dire Wolf version %d.%d (%s) Beta Test 4\n", MAJOR_VERSION, MINOR_VERSION, __DATE__); - dw_printf ("Dire Wolf DEVELOPMENT version %d.%d %s (%s)\n", MAJOR_VERSION, MINOR_VERSION, "B", __DATE__); + dw_printf ("Dire Wolf DEVELOPMENT version %d.%d %s (%s)\n", MAJOR_VERSION, MINOR_VERSION, "C", __DATE__); //dw_printf ("Dire Wolf version %d.%d\n", MAJOR_VERSION, MINOR_VERSION); @@ -382,7 +382,7 @@ int main (int argc, char *argv[]) if (getuid() == 0 || geteuid() == 0) { text_color_set(DW_COLOR_ERROR); dw_printf ("Dire Wolf requires only privileges available to ordinary users.\n"); - dw_printf ("Running this as root is an unnecssary security risk.\n"); + dw_printf ("Running this as root is an unnecessary security risk.\n"); } #endif @@ -776,7 +776,7 @@ int main (int argc, char *argv[]) if (n_opt != 0) { audio_config.adev[0].num_channels = n_opt; if (n_opt == 2) { - audio_config.achan[1].medium = MEDIUM_RADIO; + audio_config.chan_medium[1] = MEDIUM_RADIO; } } @@ -1027,7 +1027,7 @@ int main (int argc, char *argv[]) */ if (x_opt_mode != ' ') { - if (audio_config.achan[x_opt_chan].medium == MEDIUM_RADIO) { + if (audio_config.chan_medium[x_opt_chan] == MEDIUM_RADIO) { if (audio_config.achan[x_opt_chan].mark_freq && audio_config.achan[x_opt_chan].space_freq) { int max_duration = 60; @@ -1183,8 +1183,8 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev int h; char display_retries[32]; - assert (chan >= 0 && chan < MAX_CHANS); - assert (subchan >= -1 && subchan < MAX_SUBCHANS); + assert (chan >= 0 && chan < MAX_TOTAL_CHANS); // TOTAL for virtual channels + assert (subchan >= -2 && subchan < MAX_SUBCHANS); assert (slice >= 0 && slice < MAX_SLICERS); assert (pp != NULL); // 1.1J+ @@ -1220,8 +1220,11 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev text_color_set(DW_COLOR_DEBUG); dw_printf ("\n"); - if (( ! q_h_opt ) && alevel.rec >= 0) { /* suppress if "-q h" option */ +// The HEARD line. + if (( ! q_h_opt ) && alevel.rec >= 0) { /* suppress if "-q h" option */ +// FIXME: rather than checking for ichannel, how about checking medium==radio + if (chan != audio_config.igate_vchannel) { // suppress if from ICHANNEL if (h != -1 && h != AX25_SOURCE) { dw_printf ("Digipeater "); } @@ -1264,6 +1267,7 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev dw_printf ("%s audio level = %s %s %s\n", heard, alevel_text, display_retries, spectrum); } + } } /* Version 1.2: Cranking the input level way up produces 199. */ @@ -1277,7 +1281,8 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev text_color_set(DW_COLOR_ERROR); dw_printf ("Audio input level is too high. Reduce so most stations are around 50.\n"); } - else if (alevel.rec < 5) { +// FIXME: rather than checking for ichannel, how about checking medium==radio + else if (alevel.rec < 5 && chan != audio_config.igate_vchannel) { text_color_set(DW_COLOR_ERROR); dw_printf ("Audio input level is too low. Increase so most stations are around 50.\n"); @@ -1306,6 +1311,10 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev text_color_set(DW_COLOR_REC); dw_printf ("[%d.dtmf%s] ", chan, ts); } + else if (subchan == -2) { + text_color_set(DW_COLOR_REC); + dw_printf ("[%d.is%s] ", chan, ts); + } else { if (ax25_is_aprs(pp)) { text_color_set(DW_COLOR_REC); @@ -1513,6 +1522,16 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev } } +/* + * If it is from the ICHANNEL, we are done. + * Don't digipeat. Don't IGate. + * Don't do anything with it after printing and sending to client apps. + */ + + if (chan == audio_config.igate_vchannel) { + return; + } + /* * If it came from DTMF decoder (subchan == -1), send it to APRStt gateway. * Otherwise, it is a candidate for IGate and digipeater. diff --git a/src/direwolf.h b/src/direwolf.h index f5b6cfd..8351e1a 100644 --- a/src/direwolf.h +++ b/src/direwolf.h @@ -64,7 +64,15 @@ * and make sure they handle undefined channels correctly. */ -#define MAX_CHANS ((MAX_ADEVS) * 2) +#define MAX_RADIO_CHANS ((MAX_ADEVS) * 2) + +#define MAX_CHANS MAX_RADIO_CHANS // TODO: Replace all former with latter to avoid confusion with following. + +#define MAX_TOTAL_CHANS 16 // v1.7 allows additional virtual channels which are connected + // to something other than radio modems. + // Total maximum channels is based on the 4 bit KISS field. + // Someone with very unusual requirements could increase this and + // use only the AGW network protocol. /* * Maximum number of rigs. diff --git a/src/dlq.c b/src/dlq.c index 23f4389..b729e2e 100644 --- a/src/dlq.c +++ b/src/dlq.c @@ -233,7 +233,7 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev dw_printf ("dlq_rec_frame (chan=%d, pp=%p, ...)\n", chan, pp); #endif - assert (chan >= 0 && chan < MAX_CHANS); + assert (chan >= 0 && chan < MAX_TOTAL_CHANS); // TOTAL to include virtual channels. if (pp == NULL) { text_color_set(DW_COLOR_ERROR); diff --git a/src/dtmf.c b/src/dtmf.c index 956f709..953b0f7 100644 --- a/src/dtmf.c +++ b/src/dtmf.c @@ -529,7 +529,7 @@ int main () memset (&my_audio_config, 0, sizeof(my_audio_config)); my_audio_config.adev[ACHAN2ADEV(c)].defined = 1; my_audio_config.adev[ACHAN2ADEV(c)].samples_per_sec = 44100; - my_audio_config.achan[c].medium = MEDIUM_RADIO; + my_audio_config.chan_medium[c] = MEDIUM_RADIO; my_audio_config.achan[c].dtmf_decode = DTMF_DECODE_ON; dtmf_init(&my_audio_config, 50); diff --git a/src/gen_packets.c b/src/gen_packets.c index 7f7f3b4..ba58abb 100644 --- a/src/gen_packets.c +++ b/src/gen_packets.c @@ -198,7 +198,7 @@ int main(int argc, char **argv) modem.achan[chan].baud = DEFAULT_BAUD; /* -b option */ } - modem.achan[0].medium = MEDIUM_RADIO; + modem.chan_medium[0] = MEDIUM_RADIO; /* @@ -427,7 +427,7 @@ int main(int argc, char **argv) case '2': /* -2 for 2 channels of sound */ modem.adev[0].num_channels = 2; - modem.achan[1].medium = MEDIUM_RADIO; + modem.chan_medium[1] = MEDIUM_RADIO; text_color_set(DW_COLOR_INFO); dw_printf("2 channels of sound rather than 1.\n"); break; diff --git a/src/gen_tone.c b/src/gen_tone.c index 023c0f8..3317aa3 100644 --- a/src/gen_tone.c +++ b/src/gen_tone.c @@ -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++) { - if (audio_config_p->achan[chan].medium == MEDIUM_RADIO) { + if (audio_config_p->chan_medium[chan] == MEDIUM_RADIO) { int a = ACHAN2ADEV(chan); @@ -295,7 +295,7 @@ void tone_gen_put_bit (int chan, int dat) assert (save_audio_config_p != NULL); - if (save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Invalid channel %d for tone generation.\n", chan); return; diff --git a/src/hdlc_rec.c b/src/hdlc_rec.c index 619d308..d87a1b5 100644 --- a/src/hdlc_rec.c +++ b/src/hdlc_rec.c @@ -152,7 +152,7 @@ void hdlc_rec_init (struct audio_s *pa) for (ch = 0; ch < MAX_CHANS; ch++) { - if (pa->achan[ch].medium == MEDIUM_RADIO) { + if (pa->chan_medium[ch] == MEDIUM_RADIO) { num_subchan[ch] = pa->achan[ch].num_subchan; diff --git a/src/igate.c b/src/igate.c index f4c1b57..bb63e36 100644 --- a/src/igate.c +++ b/src/igate.c @@ -100,6 +100,7 @@ #include "version.h" #include "digipeater.h" #include "tq.h" +#include "dlq.h" #include "igate.h" #include "latlong.h" #include "pfilter.h" @@ -107,6 +108,7 @@ #include "mheard.h" + #if __WIN32__ static unsigned __stdcall connnect_thread (void *arg); static unsigned __stdcall igate_recv_thread (void *arg); @@ -1469,7 +1471,7 @@ static void * igate_recv_thread (void *arg) * * Future: might have ability to configure multiple transmit * channels, each with own client side filtering and via path. - * Loop here over all configured channels. + * If so, loop here over all configured channels. */ text_color_set(DW_COLOR_REC); dw_printf ("\n[ig>tx] "); // formerly just [ig] @@ -1504,6 +1506,60 @@ static void * igate_recv_thread (void *arg) if (to_chan >= 0) { maybe_xmit_packet_from_igate ((char*)message, to_chan); } + + +/* + * New in 1.7: If ICHANNEL was specified, send packet to client app as specified channel. + */ + if (save_audio_config_p->igate_vchannel >= 0) { + + int ichan = save_audio_config_p->igate_vchannel; + + // Try to parse it into a packet object. + // This will contain "q constructs" and we might see an address + // with two alphnumeric characters in the SSID so we must use + // the non-strict parsing. + + // Possible problem: Up to 8 digipeaters are allowed in radio format. + // There is a potential of finding a larger number here. + + packet_t pp3 = ax25_from_text((char*)message, 0); // 0 means not strict + if (pp3 != NULL) { + + // Should we remove the VIA path? + + // For example, we might get something like this from the server. + // Lower case 'q' and non-numeric SSID are not valid for AX.25 over the air. + // K1USN-1>APWW10,TCPIP*,qAC,N5JXS-F1:T#479,100,048,002,500,000,10000000 + + // Should we try to retain all information and pass that along, to the best of our ability, + // to the client app, or should we remove the via path so it looks like this? + // K1USN-1>APWW10:T#479,100,048,002,500,000,10000000 + + // For now, keep it intact and see if it causes problems. Easy to remove like this: + // while (ax25_get_num_repeaters(pp3) > 0) { + // ax25_remove_addr (pp3, AX25_REPEATER_1); + // } + + alevel_t alevel; + memset (&alevel, 0, sizeof(alevel)); + alevel.mark = -2; // FIXME: Do we want some other special case? + alevel.space = -2; + + int subchan = -2; // FIXME: -1 is special case for APRStt. + // See what happens with -2 and follow up on this. + // Do we need something else here? + int slice = 0; + int is_fx25 = 0; + char spectrum[] = "APRS-IS"; + dlq_rec_frame (ichan, subchan, slice, pp3, alevel, is_fx25, RETRY_NONE, spectrum); + } + else { + text_color_set(DW_COLOR_ERROR); + dw_printf ("ICHANNEL %d: Could not parse message from APRS-IS server.\n", ichan); + dw_printf ("%s\n", message); + } + } // end ICHANNEL option } } /* while (1) */ @@ -1538,9 +1594,14 @@ static void * igate_recv_thread (void *arg) * Duplicate removal will drop the original if there is no * corresponding digipeated version. * + * + * This was an idea that came up in one of the discussion forums. + * I rushed in without thinking about it very much. + * * In retrospect, I don't think this was such a good idea. * It would be of value only if there is no other IGate nearby * that would report on the original transmission. + * I wonder if anyone would notice if this silently disappeared. * *--------------------------------------------------------------------*/ diff --git a/src/kiss_frame.c b/src/kiss_frame.c index b5e3c96..1d49809 100644 --- a/src/kiss_frame.c +++ b/src/kiss_frame.c @@ -610,7 +610,7 @@ void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, struct /* Verify that the radio channel number is valid. */ /* Any sort of medium should be OK here. */ - if (chan < 0 || chan >= MAX_CHANS || save_audio_config_p->achan[chan].medium == MEDIUM_NONE) { + if (chan < 0 || chan >= MAX_CHANS || save_audio_config_p->chan_medium[chan] == MEDIUM_NONE) { text_color_set(DW_COLOR_ERROR); dw_printf ("Invalid transmit channel %d from KISS client app.\n", chan); dw_printf ("\n"); diff --git a/src/morse.c b/src/morse.c index aec3ed6..b61e75c 100644 --- a/src/morse.c +++ b/src/morse.c @@ -313,7 +313,7 @@ static void morse_tone (int chan, int tu, int wpm) { int f1_change_per_sample; // How much to advance phase for each audio sample. - if (save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Invalid channel %d for sending Morse Code.\n", chan); return; @@ -365,7 +365,7 @@ static void morse_quiet (int chan, int tu, int wpm) { int nsamples; int j; - if (save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Invalid channel %d for sending Morse Code.\n", chan); return; @@ -404,7 +404,7 @@ static void morse_quiet_ms (int chan, int ms) { int nsamples; int j; - if (save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Invalid channel %d for sending Morse Code.\n", chan); return; diff --git a/src/multi_modem.c b/src/multi_modem.c index c738875..d02b8c2 100644 --- a/src/multi_modem.c +++ b/src/multi_modem.c @@ -172,7 +172,7 @@ void multi_modem_init (struct audio_s *pa) hdlc_rec_init (save_audio_config_p); for (chan=0; chanachan[chan].medium == MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[chan] == MEDIUM_RADIO) { if (save_audio_config_p->achan[chan].baud <= 0) { text_color_set(DW_COLOR_ERROR); dw_printf("Internal error, chan=%d, %s, %d\n", chan, __FILE__, __LINE__); diff --git a/src/ptt.c b/src/ptt.c index d37d821..3bad92c 100644 --- a/src/ptt.c +++ b/src/ptt.c @@ -737,7 +737,7 @@ void ptt_init (struct audio_s *audio_config_p) for (ch = 0; ch < MAX_CHANS; ch++) { - if (audio_config_p->achan[ch].medium == MEDIUM_RADIO) { + if (audio_config_p->chan_medium[ch] == MEDIUM_RADIO) { int ot; for (ot = 0; ot < NUM_OCTYPES; ot++) { @@ -768,7 +768,7 @@ void ptt_init (struct audio_s *audio_config_p) int j, k; for (j = ch; j >= 0; j--) { - if (audio_config_p->achan[j].medium == MEDIUM_RADIO) { + if (audio_config_p->chan_medium[j] == MEDIUM_RADIO) { 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) { fd = ptt_fd[j][k]; @@ -851,7 +851,7 @@ void ptt_init (struct audio_s *audio_config_p) using_gpio = 0; for (ch=0; chachan[ch].medium == MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[ch] == MEDIUM_RADIO) { int ot; for (ot = 0; ot < NUM_OCTYPES; ot++) { if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_GPIO) { @@ -876,7 +876,7 @@ void ptt_init (struct audio_s *audio_config_p) */ for (ch = 0; ch < MAX_CHANS; ch++) { - if (save_audio_config_p->achan[ch].medium == MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[ch] == MEDIUM_RADIO) { int ot; // output control type, PTT, DCD, CON, ... int it; // input control type @@ -908,7 +908,7 @@ void ptt_init (struct audio_s *audio_config_p) #if ( defined(__i386__) || defined(__x86_64__) ) && ( defined(__linux__) || defined(__unix__) ) for (ch = 0; ch < MAX_CHANS; ch++) { - if (save_audio_config_p->achan[ch].medium == MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[ch] == MEDIUM_RADIO) { int ot; for (ot = 0; ot < NUM_OCTYPES; ot++) { if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_LPT) { @@ -923,7 +923,7 @@ void ptt_init (struct audio_s *audio_config_p) int j, k; for (j = ch; j >= 0; j--) { - if (audio_config_p->achan[j].medium == MEDIUM_RADIO) { + if (audio_config_p->chan_medium[j] == MEDIUM_RADIO) { 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) { fd = ptt_fd[j][k]; @@ -975,7 +975,7 @@ void ptt_init (struct audio_s *audio_config_p) #ifdef USE_HAMLIB for (ch = 0; ch < MAX_CHANS; ch++) { - if (save_audio_config_p->achan[ch].medium == MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[ch] == MEDIUM_RADIO) { int ot; for (ot = 0; ot < NUM_OCTYPES; ot++) { if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_HAMLIB) { @@ -1075,7 +1075,7 @@ void ptt_init (struct audio_s *audio_config_p) for (ch = 0; ch < MAX_CHANS; ch++) { - if (audio_config_p->achan[ch].medium == MEDIUM_RADIO) { + if (audio_config_p->chan_medium[ch] == MEDIUM_RADIO) { int ot; for (ot = 0; ot < NUM_OCTYPES; ot++) { if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_CM108) { @@ -1096,7 +1096,7 @@ void ptt_init (struct audio_s *audio_config_p) /* Why doesn't it transmit? Probably forgot to specify PTT option. */ for (ch=0; chachan[ch].medium == MEDIUM_RADIO) { + if (audio_config_p->chan_medium[ch] == MEDIUM_RADIO) { if(audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_method == PTT_METHOD_NONE) { text_color_set(DW_COLOR_INFO); dw_printf ("Note: PTT not configured for channel %d. (Ignore this if using VOX.)\n", ch); @@ -1148,7 +1148,7 @@ void ptt_set (int ot, int chan, int ptt_signal) assert (chan >= 0 && chan < MAX_CHANS); - if ( save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) { + if ( save_audio_config_p->chan_medium[chan] != MEDIUM_RADIO) { 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); return; @@ -1359,7 +1359,7 @@ int get_input (int it, int chan) assert (it >= 0 && it < NUM_ICTYPES); assert (chan >= 0 && chan < MAX_CHANS); - if ( save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) { + if ( save_audio_config_p->chan_medium[chan] != MEDIUM_RADIO) { text_color_set(DW_COLOR_ERROR); dw_printf ("Internal error, get_input ( %d, %d ), did not expect invalid channel.\n", it, chan); return -1; @@ -1423,7 +1423,7 @@ void ptt_term (void) int n; for (n = 0; n < MAX_CHANS; n++) { - if (save_audio_config_p->achan[n].medium == MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[n] == MEDIUM_RADIO) { int ot; for (ot = 0; ot < NUM_OCTYPES; ot++) { ptt_set (ot, n, 0); @@ -1432,7 +1432,7 @@ void ptt_term (void) } for (n = 0; n < MAX_CHANS; n++) { - if (save_audio_config_p->achan[n].medium == MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[n] == MEDIUM_RADIO) { int ot; for (ot = 0; ot < NUM_OCTYPES; ot++) { if (ptt_fd[n][ot] != INVALID_HANDLE_VALUE) { @@ -1450,7 +1450,7 @@ void ptt_term (void) #ifdef USE_HAMLIB for (n = 0; n < MAX_CHANS; n++) { - if (save_audio_config_p->achan[n].medium == MEDIUM_RADIO) { + if (save_audio_config_p->chan_medium[n] == MEDIUM_RADIO) { int ot; for (ot = 0; ot < NUM_OCTYPES; ot++) { if (rig[n][ot] != NULL) { @@ -1489,14 +1489,14 @@ int main () my_audio_config.adev[0].num_channels = 2; - my_audio_config.achan[0].medium = MEDIUM_RADIO; + my_audio_config.chan_medium[0] = MEDIUM_RADIO; my_audio_config.achan[0].octrl[OCTYPE_PTT].ptt_method = PTT_METHOD_SERIAL; // 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, "/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[1].medium = MEDIUM_RADIO; + my_audio_config.chan_medium[1] = MEDIUM_RADIO; 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, "/dev/ttyUSB0", sizeof(my_audio_config.achan[1].octrl[OCTYPE_PTT].ptt_device)); @@ -1570,7 +1570,7 @@ int main () memset (&my_audio_config, 0, sizeof(my_audio_config)); my_audio_config.adev[0].num_channels = 1; - my_audio_config.achan[0].medium = MEDIUM_RADIO; + my_audio_config.chan_medium[0] = MEDIUM_RADIO; 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; @@ -1601,10 +1601,10 @@ int main () #if 0 memset (&my_audio_config, 0, sizeof(my_audio_config)); my_audio_config.num_channels = 2; - my_audio_config.achan[0].medium = MEDIUM_RADIO; + my_audio_config.chan_medium[0] = MEDIUM_RADIO; 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.achan[1].medium = MEDIUM_RADIO; + my_audio_config.chan_medium[1] = MEDIUM_RADIO; 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; diff --git a/src/server.c b/src/server.c index ee3b9b5..57dde72 100644 --- a/src/server.c +++ b/src/server.c @@ -1538,9 +1538,9 @@ static THREAD_F cmd_listen_thread (void *arg) count = 0; for (j=0; jachan[j].medium == MEDIUM_RADIO || - save_audio_config_p->achan[j].medium == MEDIUM_IGATE || - save_audio_config_p->achan[j].medium == MEDIUM_NETTNC) { + if (save_audio_config_p->chan_medium[j] == MEDIUM_RADIO || + save_audio_config_p->chan_medium[j] == MEDIUM_IGATE || + save_audio_config_p->chan_medium[j] == MEDIUM_NETTNC) { count++; } } @@ -1548,7 +1548,7 @@ static THREAD_F cmd_listen_thread (void *arg) for (j=0; jachan[j].medium) { + switch (save_audio_config_p->chan_medium[j]) { case MEDIUM_RADIO: { @@ -1827,7 +1827,7 @@ static THREAD_F cmd_listen_thread (void *arg) // Connected mode can only be used with internal modems. - if (chan >= 0 && chan < MAX_CHANS && save_audio_config_p->achan[chan].medium == MEDIUM_RADIO) { + if (chan >= 0 && chan < MAX_CHANS && save_audio_config_p->chan_medium[chan] == MEDIUM_RADIO) { ok = 1; dlq_register_callsign (cmd.hdr.call_from, chan, client); } @@ -1856,7 +1856,7 @@ static THREAD_F cmd_listen_thread (void *arg) // Connected mode can only be used with internal modems. - if (chan >= 0 && chan < MAX_CHANS && save_audio_config_p->achan[chan].medium == MEDIUM_RADIO) { + if (chan >= 0 && chan < MAX_CHANS && save_audio_config_p->chan_medium[chan] == MEDIUM_RADIO) { dlq_unregister_callsign (cmd.hdr.call_from, chan, client); } else { diff --git a/src/tq.c b/src/tq.c index 0cc4bec..3d1b056 100644 --- a/src/tq.c +++ b/src/tq.c @@ -148,7 +148,7 @@ void tq_init (struct audio_s *audio_config_p) for (c = 0; c < MAX_CHANS; c++) { - if (audio_config_p->achan[c].medium == MEDIUM_RADIO) { + if (audio_config_p->chan_medium[c] == MEDIUM_RADIO) { 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; - if (audio_config_p->achan[c].medium == MEDIUM_RADIO) { + if (audio_config_p->chan_medium[c] == MEDIUM_RADIO) { err = pthread_cond_init (&(wake_up_cond[c]), NULL); if (err != 0) { text_color_set(DW_COLOR_ERROR); @@ -247,7 +247,7 @@ void tq_append (int chan, int prio, packet_t pp) } #endif - if (chan < 0 || chan >= MAX_CHANS || save_audio_config_p->achan[chan].medium == MEDIUM_NONE) { + if (chan < 0 || chan >= MAX_CHANS || save_audio_config_p->chan_medium[chan] == MEDIUM_NONE) { text_color_set(DW_COLOR_ERROR); 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"); @@ -451,7 +451,7 @@ void lm_data_request (int chan, int prio, packet_t pp) } #endif - if (chan < 0 || chan >= MAX_CHANS || save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) { + if (chan < 0 || chan >= MAX_CHANS || save_audio_config_p->chan_medium[chan] != MEDIUM_RADIO) { // Connected mode is allowed only with internal modems. text_color_set(DW_COLOR_ERROR); dw_printf ("ERROR - Request to transmit on invalid radio channel %d.\n", chan); @@ -609,7 +609,7 @@ void lm_seize_request (int chan) #endif - if (chan < 0 || chan >= MAX_CHANS || save_audio_config_p->achan[chan].medium != MEDIUM_RADIO) { + if (chan < 0 || chan >= MAX_CHANS || save_audio_config_p->chan_medium[chan] != MEDIUM_RADIO) { // Connected mode is allowed only with internal modems. text_color_set(DW_COLOR_ERROR); dw_printf ("ERROR - Request to transmit on invalid radio channel %d.\n", chan); diff --git a/src/xmit.c b/src/xmit.c index 65faafd..9494dac 100644 --- a/src/xmit.c +++ b/src/xmit.c @@ -278,7 +278,7 @@ void xmit_init (struct audio_s *p_modem, int debug_xmit_packet) for (j=0; jachan[j].medium == MEDIUM_RADIO) { + if (p_modem->chan_medium[j] == MEDIUM_RADIO) { #if __WIN32__ xmit_th[j] = (HANDLE)_beginthreadex (NULL, 0, xmit_thread, (void*)(ptrdiff_t)j, 0, NULL); if (xmit_th[j] == NULL) {