Add time slots for beacons.

This commit is contained in:
WB2OSZ 2017-06-11 16:57:43 -04:00
parent 979fdf1767
commit 0da1a9176a
6 changed files with 166 additions and 56 deletions

View File

@ -1,6 +1,21 @@
# Revision History # # Revision History #
## Version 1.5 -- Development snapshot B -- June 2017 ##
This is a snapshot of ongoing development towards version of 1.5. Some features might be incomplete or broken or not documented properly.
### New Features: ###
- Time slots for beaconing.
- V20 configuration item for listing stations known not to understaand AX.25 v2.2. This will speed up connection by going right to SABM and not trying SABME first and failing.
- Documentation updates describing cheap SDR frequency inaccuracy and how to compensate for it.
### Bugs Fixed: ###
- PACLEN configuration item no longer restricts length of received frames.
## Version 1.5 -- Development snapshot A -- May 2017 ## ## Version 1.5 -- Development snapshot A -- May 2017 ##

172
beacon.c
View File

@ -1,7 +1,7 @@
// //
// This file is part of Dire Wolf, an amateur radio packet TNC. // This file is part of Dire Wolf, an amateur radio packet TNC.
// //
// Copyright (C) 2011, 2013, 2014, 2015, 2016 John Langner, WB2OSZ // Copyright (C) 2011, 2013, 2014, 2015, 2016, 2017 John Langner, WB2OSZ
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -141,6 +141,7 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo);
void beacon_init (struct audio_s *pmodem, struct misc_config_s *pconfig, struct igate_config_s *pigate) void beacon_init (struct audio_s *pmodem, struct misc_config_s *pconfig, struct igate_config_s *pigate)
{ {
time_t now; time_t now;
struct tm tm;
int j; int j;
int count; int count;
#if __WIN32__ #if __WIN32__
@ -270,21 +271,71 @@ void beacon_init (struct audio_s *pmodem, struct misc_config_s *pconfig, struct
} }
/* /*
* Calculate first time for each beacon from the 'delay' value. * Calculate first time for each beacon from the 'slot' or 'delay' value.
*/ */
now = time(NULL); now = time(NULL);
localtime_r (&now, &tm);
for (j=0; j<g_misc_config_p->num_beacons; j++) { for (j=0; j<g_misc_config_p->num_beacons; j++) {
struct beacon_s *bp = & (g_misc_config_p->beacon[j]);
#if DEBUG #if DEBUG
text_color_set(DW_COLOR_DEBUG); text_color_set(DW_COLOR_DEBUG);
dw_printf ("beacon[%d] chan=%d, delay=%d, every=%d\n", dw_printf ("beacon[%d] chan=%d, delay=%d, slot=%d, every=%d\n",
j, j,
g_misc_config_p->beacon[j].sendto_chan, bp->sendto_chan,
g_misc_config_p->beacon[j].delay, bp->delay,
g_misc_config_p->beacon[j].every); bp->slot,
bp->every);
#endif #endif
/*
* If timeslots, there must be a full number of beacon intervals per hour.
*/
#define IS_GOOD(x) ((3600/(x))*(x) == 3600)
if (bp->slot != G_UNKNOWN) {
if ( ! IS_GOOD(bp->every)) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Config file, line %d: When using timeslots, there must be a whole number of beacon intervals per hour.\n", bp->lineno);
// Try to make it valid by adjusting up or down.
int n;
for (n=1; ; n++) {
int e;
e = bp->every + n;
if (e > 3600) {
bp->every = 3600;
break;
}
if (IS_GOOD(e)) {
bp->every = e;
break;
}
e = bp->every - n;
if (e < 1) {
bp->every = 1; // Impose a larger minimum?
break;
}
if (IS_GOOD(e)) {
bp->every = e;
break;
}
}
text_color_set(DW_COLOR_ERROR);
dw_printf ("Config file, line %d: Time between slotted beacons has been adjusted to %d seconds.\n", bp->lineno, bp->every);
}
/*
* Determine when next slot time will arrive.
*/
bp->delay = bp->slot - (tm.tm_min * 60 + tm.tm_sec);
while (bp->delay > bp->every) bp->delay -= bp->every;
while (bp->delay < 5) bp->delay += bp->every;
}
g_misc_config_p->beacon[j].next = now + g_misc_config_p->beacon[j].delay; g_misc_config_p->beacon[j].next = now + g_misc_config_p->beacon[j].delay;
} }
@ -491,10 +542,12 @@ static void * beacon_thread (void *arg)
*/ */
for (j=0; j<g_misc_config_p->num_beacons; j++) { for (j=0; j<g_misc_config_p->num_beacons; j++) {
if (g_misc_config_p->beacon[j].btype == BEACON_IGNORE) struct beacon_s *bp = & (g_misc_config_p->beacon[j]);
if (bp->btype == BEACON_IGNORE)
continue; continue;
if (g_misc_config_p->beacon[j].next <= now) { if (bp->next <= now) {
/* Send the beacon. */ /* Send the beacon. */
@ -503,13 +556,20 @@ static void * beacon_thread (void *arg)
/* Calculate when the next one should be sent. */ /* Calculate when the next one should be sent. */
/* Easy for fixed interval. SmartBeaconing takes more effort. */ /* Easy for fixed interval. SmartBeaconing takes more effort. */
if (g_misc_config_p->beacon[j].btype == BEACON_TRACKER) { if (bp->btype == BEACON_TRACKER) {
if (gpsinfo.fix < DWFIX_2D) { if (gpsinfo.fix < DWFIX_2D) {
/* Fix not available so beacon was not sent. */ /* Fix not available so beacon was not sent. */
/* Try again in a couple seconds. */
g_misc_config_p->beacon[j].next = now + 2; if (g_misc_config_p->sb_configured) {
/* Try again in a couple seconds. */
bp->next = now + 2;
}
else {
/* Stay with the schedule. */
/* Important for slotted. Might reconsider otherwise. */
bp->next += bp->every;
}
} }
else if (g_misc_config_p->sb_configured) { else if (g_misc_config_p->sb_configured) {
@ -519,18 +579,21 @@ static void * beacon_thread (void *arg)
sb_prev_time = now; sb_prev_time = now;
sb_prev_course = gpsinfo.track; sb_prev_course = gpsinfo.track;
g_misc_config_p->beacon[j].next = sb_calculate_next_time (now, bp->next = sb_calculate_next_time (now,
DW_KNOTS_TO_MPH(gpsinfo.speed_knots), gpsinfo.track, DW_KNOTS_TO_MPH(gpsinfo.speed_knots), gpsinfo.track,
sb_prev_time, sb_prev_course); sb_prev_time, sb_prev_course);
} }
else { else {
g_misc_config_p->beacon[j].next = now + g_misc_config_p->beacon[j].every; /* Tracker beacon, fixed spacing. */
bp->next += bp->every;
} }
} }
else { else {
/* non-tracker beacons are at fixed spacing. */ /* Non-tracker beacon, fixed spacing. */
/* Increment by 'every' so slotted times come out right. */
/* i.e. Don't take relative to now in case there was some delay. */
g_misc_config_p->beacon[j].next = now + g_misc_config_p->beacon[j].every; bp->next += bp->every;
} }
} /* if time to send it */ } /* if time to send it */
@ -682,6 +745,7 @@ static time_t sb_calculate_next_time (time_t now,
static void beacon_send (int j, dwgps_info_t *gpsinfo) static void beacon_send (int j, dwgps_info_t *gpsinfo)
{ {
struct beacon_s *bp = & (g_misc_config_p->beacon[j]);
int strict = 1; /* Strict packet checking because they will go over air. */ int strict = 1; /* Strict packet checking because they will go over air. */
char stemp[20]; char stemp[20];
@ -704,13 +768,13 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
*/ */
strlcpy (mycall, "NOCALL", sizeof(mycall)); strlcpy (mycall, "NOCALL", sizeof(mycall));
assert (g_misc_config_p->beacon[j].sendto_chan >= 0); assert (bp->sendto_chan >= 0);
strlcpy (mycall, g_modem_config_p->achan[g_misc_config_p->beacon[j].sendto_chan].mycall, sizeof(mycall)); strlcpy (mycall, g_modem_config_p->achan[bp->sendto_chan].mycall, sizeof(mycall));
if (strlen(mycall) == 0 || strcmp(mycall, "NOCALL") == 0) { if (strlen(mycall) == 0 || strcmp(mycall, "NOCALL") == 0) {
text_color_set(DW_COLOR_ERROR); text_color_set(DW_COLOR_ERROR);
dw_printf ("MYCALL not set for beacon in config file line %d.\n", g_misc_config_p->beacon[j].lineno); dw_printf ("MYCALL not set for beacon in config file line %d.\n", bp->lineno);
return; return;
} }
@ -723,17 +787,17 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
strlcpy (beacon_text, mycall, sizeof(beacon_text)); strlcpy (beacon_text, mycall, sizeof(beacon_text));
strlcat (beacon_text, ">", sizeof(beacon_text)); strlcat (beacon_text, ">", sizeof(beacon_text));
if (g_misc_config_p->beacon[j].dest != NULL) { if (bp->dest != NULL) {
strlcat (beacon_text, g_misc_config_p->beacon[j].dest, sizeof(beacon_text)); strlcat (beacon_text, bp->dest, sizeof(beacon_text));
} }
else { else {
snprintf (stemp, sizeof(stemp), "%s%1d%1d", APP_TOCALL, MAJOR_VERSION, MINOR_VERSION); snprintf (stemp, sizeof(stemp), "%s%1d%1d", APP_TOCALL, MAJOR_VERSION, MINOR_VERSION);
strlcat (beacon_text, stemp, sizeof(beacon_text)); strlcat (beacon_text, stemp, sizeof(beacon_text));
} }
if (g_misc_config_p->beacon[j].via != NULL) { if (bp->via != NULL) {
strlcat (beacon_text, ",", sizeof(beacon_text)); strlcat (beacon_text, ",", sizeof(beacon_text));
strlcat (beacon_text, g_misc_config_p->beacon[j].via, sizeof(beacon_text)); strlcat (beacon_text, bp->via, sizeof(beacon_text));
} }
strlcat (beacon_text, ":", sizeof(beacon_text)); strlcat (beacon_text, ":", sizeof(beacon_text));
@ -746,23 +810,23 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
// TODO: test & document. // TODO: test & document.
strlcpy (super_comment, "", sizeof(super_comment)); strlcpy (super_comment, "", sizeof(super_comment));
if (g_misc_config_p->beacon[j].comment != NULL) { if (bp->comment != NULL) {
strlcpy (super_comment, g_misc_config_p->beacon[j].comment, sizeof(super_comment)); strlcpy (super_comment, bp->comment, sizeof(super_comment));
} }
if (g_misc_config_p->beacon[j].commentcmd != NULL) { if (bp->commentcmd != NULL) {
char var_comment[AX25_MAX_INFO_LEN]; char var_comment[AX25_MAX_INFO_LEN];
int k; int k;
/* Run given command to get variable part of comment. */ /* Run given command to get variable part of comment. */
k = dw_run_cmd (g_misc_config_p->beacon[j].commentcmd, 2, var_comment, sizeof(var_comment)); k = dw_run_cmd (bp->commentcmd, 2, var_comment, sizeof(var_comment));
if (k > 0) { if (k > 0) {
strlcat (super_comment, var_comment, sizeof(super_comment)); strlcat (super_comment, var_comment, sizeof(super_comment));
} }
else { else {
text_color_set(DW_COLOR_ERROR); text_color_set(DW_COLOR_ERROR);
dw_printf ("xBEACON, config file line %d, COMMENTCMD failure.\n", g_misc_config_p->beacon[j].lineno); dw_printf ("xBEACON, config file line %d, COMMENTCMD failure.\n", bp->lineno);
} }
} }
@ -770,17 +834,17 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
/* /*
* Add the info part depending on beacon type. * Add the info part depending on beacon type.
*/ */
switch (g_misc_config_p->beacon[j].btype) { switch (bp->btype) {
case BEACON_POSITION: case BEACON_POSITION:
encode_position (g_misc_config_p->beacon[j].messaging, g_misc_config_p->beacon[j].compress, encode_position (bp->messaging, bp->compress,
g_misc_config_p->beacon[j].lat, g_misc_config_p->beacon[j].lon, 0, bp->lat, bp->lon, 0,
(int)roundf(DW_METERS_TO_FEET(g_misc_config_p->beacon[j].alt_m)), (int)roundf(DW_METERS_TO_FEET(bp->alt_m)),
g_misc_config_p->beacon[j].symtab, g_misc_config_p->beacon[j].symbol, bp->symtab, bp->symbol,
g_misc_config_p->beacon[j].power, g_misc_config_p->beacon[j].height, g_misc_config_p->beacon[j].gain, g_misc_config_p->beacon[j].dir, bp->power, bp->height, bp->gain, bp->dir,
G_UNKNOWN, G_UNKNOWN, /* course, speed */ G_UNKNOWN, G_UNKNOWN, /* course, speed */
g_misc_config_p->beacon[j].freq, g_misc_config_p->beacon[j].tone, g_misc_config_p->beacon[j].offset, bp->freq, bp->tone, bp->offset,
super_comment, super_comment,
info, sizeof(info)); info, sizeof(info));
strlcat (beacon_text, info, sizeof(beacon_text)); strlcat (beacon_text, info, sizeof(beacon_text));
@ -788,11 +852,11 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
case BEACON_OBJECT: case BEACON_OBJECT:
encode_object (g_misc_config_p->beacon[j].objname, g_misc_config_p->beacon[j].compress, 0, g_misc_config_p->beacon[j].lat, g_misc_config_p->beacon[j].lon, 0, encode_object (bp->objname, bp->compress, 0, bp->lat, bp->lon, 0,
g_misc_config_p->beacon[j].symtab, g_misc_config_p->beacon[j].symbol, bp->symtab, bp->symbol,
g_misc_config_p->beacon[j].power, g_misc_config_p->beacon[j].height, g_misc_config_p->beacon[j].gain, g_misc_config_p->beacon[j].dir, bp->power, bp->height, bp->gain, bp->dir,
G_UNKNOWN, G_UNKNOWN, /* course, speed */ G_UNKNOWN, G_UNKNOWN, /* course, speed */
g_misc_config_p->beacon[j].freq, g_misc_config_p->beacon[j].tone, g_misc_config_p->beacon[j].offset, super_comment, bp->freq, bp->tone, bp->offset, super_comment,
info, sizeof(info)); info, sizeof(info));
strlcat (beacon_text, info, sizeof(beacon_text)); strlcat (beacon_text, info, sizeof(beacon_text));
break; break;
@ -809,7 +873,7 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
/* transmission of altitude from GPS. */ /* transmission of altitude from GPS. */
my_alt_ft = G_UNKNOWN; my_alt_ft = G_UNKNOWN;
if (gpsinfo->fix >= 3 && gpsinfo->altitude != G_UNKNOWN && g_misc_config_p->beacon[j].alt_m > 0) { if (gpsinfo->fix >= 3 && gpsinfo->altitude != G_UNKNOWN && bp->alt_m > 0) {
my_alt_ft = (int)roundf(DW_METERS_TO_FEET(gpsinfo->altitude)); my_alt_ft = (int)roundf(DW_METERS_TO_FEET(gpsinfo->altitude));
} }
@ -818,12 +882,12 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
coarse = (int)roundf(gpsinfo->track); coarse = (int)roundf(gpsinfo->track);
} }
encode_position (g_misc_config_p->beacon[j].messaging, g_misc_config_p->beacon[j].compress, encode_position (bp->messaging, bp->compress,
gpsinfo->dlat, gpsinfo->dlon, 0, my_alt_ft, gpsinfo->dlat, gpsinfo->dlon, 0, my_alt_ft,
g_misc_config_p->beacon[j].symtab, g_misc_config_p->beacon[j].symbol, bp->symtab, bp->symbol,
g_misc_config_p->beacon[j].power, g_misc_config_p->beacon[j].height, g_misc_config_p->beacon[j].gain, g_misc_config_p->beacon[j].dir, bp->power, bp->height, bp->gain, bp->dir,
coarse, (int)roundf(gpsinfo->speed_knots), coarse, (int)roundf(gpsinfo->speed_knots),
g_misc_config_p->beacon[j].freq, g_misc_config_p->beacon[j].tone, g_misc_config_p->beacon[j].offset, bp->freq, bp->tone, bp->offset,
super_comment, super_comment,
info, sizeof(info)); info, sizeof(info));
strlcat (beacon_text, info, sizeof(beacon_text)); strlcat (beacon_text, info, sizeof(beacon_text));
@ -845,8 +909,8 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
A.g_dcs = G_UNKNOWN; A.g_dcs = G_UNKNOWN;
strlcpy (A.g_src, mycall, sizeof(A.g_src)); strlcpy (A.g_src, mycall, sizeof(A.g_src));
A.g_symbol_table = g_misc_config_p->beacon[j].symtab; A.g_symbol_table = bp->symtab;
A.g_symbol_code = g_misc_config_p->beacon[j].symbol; A.g_symbol_code = bp->symbol;
A.g_lat = gpsinfo->dlat; A.g_lat = gpsinfo->dlat;
A.g_lon = gpsinfo->dlon; A.g_lon = gpsinfo->dlon;
A.g_speed_mph = DW_KNOTS_TO_MPH(gpsinfo->speed_knots); A.g_speed_mph = DW_KNOTS_TO_MPH(gpsinfo->speed_knots);
@ -865,25 +929,25 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
case BEACON_CUSTOM: case BEACON_CUSTOM:
if (g_misc_config_p->beacon[j].custom_info != NULL) { if (bp->custom_info != NULL) {
/* Fixed handcrafted text. */ /* Fixed handcrafted text. */
strlcat (beacon_text, g_misc_config_p->beacon[j].custom_info, sizeof(beacon_text)); strlcat (beacon_text, bp->custom_info, sizeof(beacon_text));
} }
else if (g_misc_config_p->beacon[j].custom_infocmd != NULL) { else if (bp->custom_infocmd != NULL) {
char info_part[AX25_MAX_INFO_LEN]; char info_part[AX25_MAX_INFO_LEN];
int k; int k;
/* Run given command to obtain the info part for packet. */ /* Run given command to obtain the info part for packet. */
k = dw_run_cmd (g_misc_config_p->beacon[j].custom_infocmd, 2, info_part, sizeof(info_part)); k = dw_run_cmd (bp->custom_infocmd, 2, info_part, sizeof(info_part));
if (k > 0) { if (k > 0) {
strlcat (beacon_text, info_part, sizeof(beacon_text)); strlcat (beacon_text, info_part, sizeof(beacon_text));
} }
else { else {
text_color_set(DW_COLOR_ERROR); text_color_set(DW_COLOR_ERROR);
dw_printf ("CBEACON, config file line %d, INFOCMD failure.\n", g_misc_config_p->beacon[j].lineno); dw_printf ("CBEACON, config file line %d, INFOCMD failure.\n", bp->lineno);
strlcpy (beacon_text, "", sizeof(beacon_text)); // abort! strlcpy (beacon_text, "", sizeof(beacon_text)); // abort!
} }
} }
@ -935,7 +999,7 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
alevel_t alevel; alevel_t alevel;
switch (g_misc_config_p->beacon[j].sendto_type) { switch (bp->sendto_type) {
case SENDTO_IGATE: case SENDTO_IGATE:
@ -949,7 +1013,7 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
case SENDTO_XMIT: case SENDTO_XMIT:
default: default:
tq_append (g_misc_config_p->beacon[j].sendto_chan, TQ_PRIO_1_LO, pp); tq_append (bp->sendto_chan, TQ_PRIO_1_LO, pp);
break; break;
case SENDTO_RECV: case SENDTO_RECV:
@ -957,13 +1021,13 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
/* Simulated reception from radio. */ /* Simulated reception from radio. */
memset (&alevel, 0xff, sizeof(alevel)); memset (&alevel, 0xff, sizeof(alevel));
dlq_rec_frame (g_misc_config_p->beacon[j].sendto_chan, 0, 0, pp, alevel, 0, ""); dlq_rec_frame (bp->sendto_chan, 0, 0, pp, alevel, 0, "");
break; break;
} }
} }
else { else {
text_color_set(DW_COLOR_ERROR); text_color_set(DW_COLOR_ERROR);
dw_printf ("Config file: Failed to parse packet constructed from line %d.\n", g_misc_config_p->beacon[j].lineno); dw_printf ("Config file: Failed to parse packet constructed from line %d.\n", bp->lineno);
dw_printf ("%s\n", beacon_text); dw_printf ("%s\n", beacon_text);
} }

View File

@ -4772,6 +4772,7 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_
b->sendto_type = SENDTO_XMIT; b->sendto_type = SENDTO_XMIT;
b->sendto_chan = 0; b->sendto_chan = 0;
b->delay = 60; b->delay = 60;
b->slot = G_UNKNOWN;
b->every = 600; b->every = 600;
//b->delay = 6; // temp test. //b->delay = 6; // temp test.
//b->every = 3600; //b->every = 3600;
@ -4805,6 +4806,15 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_
if (strcasecmp(keyword, "DELAY") == 0) { if (strcasecmp(keyword, "DELAY") == 0) {
b->delay = parse_interval(value,line); b->delay = parse_interval(value,line);
} }
else if (strcasecmp(keyword, "SLOT") == 0) {
int n = parse_interval(value,line);
if ( n < 1 || n > 3600) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Config file, line %d: Beacon time slot, %d, must be in range of 1 to 3600 seconds.\n", line, n);
continue;
}
b->slot = n;
}
else if (strcasecmp(keyword, "EVERY") == 0) { else if (strcasecmp(keyword, "EVERY") == 0) {
b->every = parse_interval(value,line); b->every = parse_interval(value,line);
} }
@ -4817,7 +4827,7 @@ static int beacon_options(char *cmd, struct beacon_s *b, int line, struct audio_
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].valid) {
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: Simulated receive on channel %d is not valid.\n", line, n);
continue; continue;
} }
b->sendto_type = SENDTO_RECV; b->sendto_type = SENDTO_RECV;

View File

@ -135,6 +135,9 @@ struct misc_config_s {
int delay; /* Seconds to delay before first transmission. */ int delay; /* Seconds to delay before first transmission. */
int slot; /* Seconds after hour for slotted time beacons. */
/* If specified, it overrides any 'delay' value. */
int every; /* Time between transmissions, seconds. */ int every; /* Time between transmissions, seconds. */
/* Remains fixed for PBEACON and OBEACON. */ /* Remains fixed for PBEACON and OBEACON. */
/* Dynamically adjusted for TBEACON. */ /* Dynamically adjusted for TBEACON. */

View File

@ -196,6 +196,7 @@ int main (int argc, char *argv[])
char P_opt[16]; char P_opt[16];
char l_opt[80]; char l_opt[80];
char input_file[80]; char input_file[80];
// char timestamp[16];
int t_opt = 1; /* Text color option. */ int t_opt = 1; /* Text color option. */
int a_opt = 0; /* "-a n" interval, in seconds, for audio statistics report. 0 for none. */ int a_opt = 0; /* "-a n" interval, in seconds, for audio statistics report. 0 for none. */
@ -261,9 +262,18 @@ int main (int argc, char *argv[])
text_color_init(t_opt); text_color_init(t_opt);
text_color_set(DW_COLOR_INFO); text_color_set(DW_COLOR_INFO);
//dw_printf ("Dire Wolf version %d.%d (%s) Beta Test\n", MAJOR_VERSION, MINOR_VERSION, __DATE__); //dw_printf ("Dire Wolf version %d.%d (%s) Beta Test\n", MAJOR_VERSION, MINOR_VERSION, __DATE__);
dw_printf ("Dire Wolf DEVELOPMENT version %d.%d %s (%s)\n", MAJOR_VERSION, MINOR_VERSION, "A", __DATE__); dw_printf ("Dire Wolf DEVELOPMENT version %d.%d %s (%s)\n", MAJOR_VERSION, MINOR_VERSION, "B", __DATE__);
//dw_printf ("Dire Wolf version %d.%d\n", MAJOR_VERSION, MINOR_VERSION); //dw_printf ("Dire Wolf version %d.%d\n", MAJOR_VERSION, MINOR_VERSION);
// FIXME: temp test
// timestamp_now (timestamp, sizeof(timestamp), 1);
// dw_printf ("%s\n", timestamp);
#if defined(ENABLE_GPSD) || defined(USE_HAMLIB) #if defined(ENABLE_GPSD) || defined(USE_HAMLIB)
dw_printf ("Includes optional support for: "); dw_printf ("Includes optional support for: ");
#if defined(ENABLE_GPSD) #if defined(ENABLE_GPSD)
@ -881,6 +891,14 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
ax25_alevel_to_text (alevel, alevel_text); ax25_alevel_to_text (alevel, alevel_text);
// Experiment: try displaying the DC bias.
// Should be 0 for soundcard but could show mistuning with SDR.
#if 0
char bias[16];
snprintf (bias, sizeof(bias), " DC%+d", multi_modem_get_dc_average (chan));
strlcat (alevel_text, bias, sizeof(alevel_text));
#endif
/* As suggested by KJ4ERJ, if we are receiving from */ /* As suggested by KJ4ERJ, if we are receiving from */
/* WIDEn-0, it is quite likely (but not guaranteed), that */ /* WIDEn-0, it is quite likely (but not guaranteed), that */

Binary file not shown.