Fix bug: "INTERNAL ERROR: dlq_append NULL packet pointer." when using PASSALL.

Added APRStt position ambiguity option.
This commit is contained in:
WB2OSZ 2015-12-06 10:09:27 -05:00
parent b104f097e0
commit d653a534c4
16 changed files with 342 additions and 38 deletions

View File

@ -3,12 +3,16 @@
----------
## Version 1.3 -- Development snapshot H -- November 2015 ##
## Version 1.3 -- Development snapshot H -- December 2015 ##
### New Feature: ###
- New experimental demodulator. More details later.
### Bugs Fixed: ###
- "INTERNAL ERROR: dlq_append NULL packet pointer." when using PASSALL.
----------

View File

@ -1,4 +1,3 @@
//
// This file is part of Dire Wolf, an amateur radio packet TNC.
//
@ -322,6 +321,7 @@ static char m_symbol_code; // Default 'A'
static char m_loc_text[24];
static double m_longitude; // Set to G_UNKNOWN if not defined.
static double m_latitude; // Set to G_UNKNOWN if not defined.
static int m_ambiguity;
static char m_comment[200];
static char m_freq[12];
static char m_mic_e;
@ -354,8 +354,9 @@ void aprs_tt_sequence (int chan, char *msg)
m_symtab_or_overlay = '\\';
m_symbol_code = 'A';
strlcpy (m_loc_text, "", sizeof(m_loc_text));
m_longitude = G_UNKNOWN;
m_latitude = G_UNKNOWN;
m_longitude = G_UNKNOWN;
m_latitude = G_UNKNOWN;
m_ambiguity = 0;
strlcpy (m_comment, "", sizeof(m_comment));
strlcpy (m_freq, "", sizeof(m_freq));
m_mic_e = ' ';
@ -384,7 +385,7 @@ void aprs_tt_sequence (int chan, char *msg)
if (err == 0) {
err = tt_user_heard (m_callsign, m_ssid, m_symtab_or_overlay, m_symbol_code,
m_loc_text, m_latitude, m_longitude,
m_loc_text, m_latitude, m_longitude, m_ambiguity,
m_freq, m_comment, m_mic_e, m_dao);
}
@ -1254,6 +1255,18 @@ static int parse_location (char *e)
}
break;
case TTLOC_AMBIG:
if (strlen(xstr) != 1) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Expected 1 digits for the position ambiguity.\n");
return (TT_ERROR_INVALID_LOC);
}
m_ambiguity = atoi(xstr);
break;
default:
assert (0);
@ -1451,6 +1464,8 @@ static int find_ttloc_match (char *e, char *xstr, char *ystr, char *zstr, char *
*
* Cttt...tttt - General comment in Multi-press encoding.
*
* CAttt...tttt - New enhanced comment format that can handle all ASCII characters.
*
*----------------------------------------------------------------*/
static int parse_comment (char *e)
@ -1461,6 +1476,11 @@ static int parse_comment (char *e)
len = strlen(e);
if (e[1] == 'A') {
tt_ascii2d_to_text (e+2, 0, m_comment);
return (0);
}
if (len == 2 && isdigit(e[1])) {
m_mic_e = e[1];
return (0);

View File

@ -14,7 +14,7 @@
*/
struct ttloc_s {
enum { TTLOC_POINT, TTLOC_VECTOR, TTLOC_GRID, TTLOC_UTM, TTLOC_MGRS, TTLOC_USNG, TTLOC_MACRO, TTLOC_MHEAD, TTLOC_SATSQ } type;
enum { TTLOC_POINT, TTLOC_VECTOR, TTLOC_GRID, TTLOC_UTM, TTLOC_MGRS, TTLOC_USNG, TTLOC_MACRO, TTLOC_MHEAD, TTLOC_SATSQ, TTLOC_AMBIG } type;
char pattern[20]; /* e.g. B998, B5bbbdddd, B2xxyy, Byyyxxx, BAxxxx */
/* For macros, it should be all fixed digits, */
@ -61,6 +61,7 @@ struct ttloc_s {
struct {
char *definition;
} macro;
};
};

View File

@ -751,7 +751,7 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
case BEACON_POSITION:
encode_position (g_misc_config_p->beacon[j].messaging, g_misc_config_p->beacon[j].compress,
g_misc_config_p->beacon[j].lat, g_misc_config_p->beacon[j].lon,
g_misc_config_p->beacon[j].lat, g_misc_config_p->beacon[j].lon, 0,
(int)roundf(DW_METERS_TO_FEET(g_misc_config_p->beacon[j].alt_m)),
g_misc_config_p->beacon[j].symtab, g_misc_config_p->beacon[j].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,
@ -764,7 +764,7 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
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,
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,
g_misc_config_p->beacon[j].symtab, g_misc_config_p->beacon[j].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,
G_UNKNOWN, G_UNKNOWN, /* course, speed */
@ -795,7 +795,7 @@ static void beacon_send (int j, dwgps_info_t *gpsinfo)
}
encode_position (g_misc_config_p->beacon[j].messaging, g_misc_config_p->beacon[j].compress,
gpsinfo->dlat, gpsinfo->dlon, 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,
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,
coarse, (int)roundf(gpsinfo->speed_knots),

111
config.c
View File

@ -1428,6 +1428,11 @@ void config_init (char *fname, struct audio_s *p_audio_config,
}
else if (strcasecmp(t, "PASSALL") == 0) {
p_audio_config->achan[channel].passall = 1;
text_color_set(DW_COLOR_ERROR);
dw_printf ("Line %d: There is an old saying, \"Be careful what you ask for because you might get it.\"\n", line);
dw_printf ("The PASSALL option means allow all frames even when they are invalid.\n");
dw_printf ("You are asking to receive random trash and you WILL get your wish.\n");
dw_printf ("Don't complain when you see all sorts of random garbage. That's what you asked for.\n");
}
else {
text_color_set(DW_COLOR_ERROR);
@ -2823,6 +2828,81 @@ void config_init (char *fname, struct audio_s *p_audio_config,
//}
}
/*
* TTAMBIG - Define pattern to be used for Object Location Ambiguity.
*
* TTAMBIG pattern
*
* Pattern would be B[0-9A-D]x
*
* Must have exactly one x.
*/
else if (strcasecmp(t, "TTAMBIG") == 0) {
// TODO1.3: TTAMBIG To be continued...
struct ttloc_s *tl;
int j;
assert (p_tt_config->ttloc_size >= 2);
assert (p_tt_config->ttloc_len >= 0 && p_tt_config->ttloc_len <= p_tt_config->ttloc_size);
/* Allocate new space, but first, if already full, make larger. */
if (p_tt_config->ttloc_len == p_tt_config->ttloc_size) {
p_tt_config->ttloc_size += p_tt_config->ttloc_size / 2;
p_tt_config->ttloc_ptr = realloc (p_tt_config->ttloc_ptr, sizeof(struct ttloc_s) * p_tt_config->ttloc_size);
}
p_tt_config->ttloc_len++;
assert (p_tt_config->ttloc_len > 0 && p_tt_config->ttloc_len <= p_tt_config->ttloc_size);
tl = &(p_tt_config->ttloc_ptr[p_tt_config->ttloc_len-1]);
tl->type = TTLOC_AMBIG;
strlcpy(tl->pattern, "", sizeof(tl->pattern));
/* Pattern: B, optional additional button, exactly x for matching */
t = split(NULL,0);
if (t == NULL) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Line %d: Missing pattern for TTAMBIG command.\n", line);
p_tt_config->ttloc_len--;
continue;
}
strlcpy (tl->pattern, t, sizeof(tl->pattern));
if (t[0] != 'B') {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Line %d: TTAMBIG pattern must begin with upper case 'B'.\n", line);
p_tt_config->ttloc_len--;
continue;
}
/* Optionally one of 0-9ABCD */
if (strchr("ABCD", t[1]) != NULL || isdigit(t[1])) {
j = 2;
}
else {
j = 1;
}
if (strcmp(t+j, "x") != 0) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Line %d: TTAMBIG pattern must end with exactly one x in lower case.\n", line);
p_tt_config->ttloc_len--;
continue;
}
/* temp debugging */
//for (j=0; j<p_tt_config->ttloc_len; j++) {
// dw_printf ("debug ttloc %d/%d %s\n", j, p_tt_config->ttloc_size,
// p_tt_config->ttloc_ptr[j].pattern);
//}
}
/*
* TTMACRO - Define compact message format with full expansion
*
@ -3034,6 +3114,37 @@ void config_init (char *fname, struct audio_s *p_audio_config,
}
}
else if (strncmp(pi, "CA{", 3) == 0) {
// Convert to enhanced comment that can contain any ASCII character.
pi += 3;
ps = stemp;
while (*pi != '}' && *pi != '*' && *pi != '\0') {
*ps++ = *pi++;
}
if (*pi == '}') {
*ps = '\0';
if (tt_text_to_ascii2d (stemp, 0, ttemp) == 0) {
//text_color_set(DW_COLOR_DEBUG);
//dw_printf ("DEBUG Line %d: CA{%s} -> CA%s\n", line, stemp, ttemp);
strlcat (otemp, "CA", sizeof(otemp));
strlcat (otemp, ttemp, sizeof(otemp));
}
else {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Line %d: CA{%s} could not be converted to tones for enhanced comment.\n", line, stemp);
tt_error++;
}
}
else {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Line %d: CA{... is missing matching } in TTMACRO definition.\n", line);
tt_error++;
}
}
else if (strchr("0123456789ABCD*#xyz", *pi) != NULL) {
t2[0] = *pi;
strlcat (otemp, t2, sizeof(otemp));

2
dlq.c
View File

@ -254,7 +254,7 @@ void dlq_append (dlq_type_t type, int chan, int subchan, int slice, packet_t pp,
assert (chan >= 0 && chan < MAX_CHANS);
if (pp == NULL) {
text_color_set(DW_COLOR_DEBUG);
text_color_set(DW_COLOR_ERROR);
dw_printf ("INTERNAL ERROR: dlq_append NULL packet pointer. Please report this!\n");
return;
}

Binary file not shown.

Binary file not shown.

View File

@ -60,6 +60,7 @@
* symbol - Symbol id.
* dlat - Latitude.
* dlong - Longitude.
* ambiguity - Blank out least significant digits.
*
* Outputs: presult - Stored here.
*
@ -77,10 +78,10 @@ typedef struct position_s {
} position_t;
static int set_norm_position (char symtab, char symbol, double dlat, double dlong, position_t *presult)
static int set_norm_position (char symtab, char symbol, double dlat, double dlong, int ambiguity, position_t *presult)
{
latitude_to_str (dlat, 0, presult->lat);
latitude_to_str (dlat, ambiguity, presult->lat);
if (symtab != '/' && symtab != '\\' && ! isdigit(symtab) && ! isupper(symtab)) {
text_color_set(DW_COLOR_ERROR);
@ -88,7 +89,7 @@ static int set_norm_position (char symtab, char symbol, double dlat, double dlon
}
presult->sym_table_id = symtab;
longitude_to_str (dlong, 0, presult->lon);
longitude_to_str (dlong, ambiguity, presult->lon);
if (symbol < '!' || symbol > '~') {
text_color_set(DW_COLOR_ERROR);
@ -480,6 +481,7 @@ static int frequency_spec (float freq, float tone, float offset, char *presult)
* compressed - Send in compressed form?
* lat - Latitude.
* lon - Longitude.
* ambiguity - Number of digits to omit from location.
* alt_ft - Altitude in feet.
* symtab - Symbol table id or overlay.
* symbol - Symbol id.
@ -535,7 +537,7 @@ typedef struct aprs_compressed_pos_s {
} aprs_compressed_pos_t;
int encode_position (int messaging, int compressed, double lat, double lon, int alt_ft,
int encode_position (int messaging, int compressed, double lat, double lon, int ambiguity, int alt_ft,
char symtab, char symbol,
int power, int height, int gain, char *dir,
int course, int speed,
@ -559,7 +561,7 @@ int encode_position (int messaging, int compressed, double lat, double lon, int
aprs_ll_pos_t *p = (aprs_ll_pos_t *)presult;
p->dti = messaging ? '=' : '!';
set_norm_position (symtab, symbol, lat, lon, &(p->pos));
set_norm_position (symtab, symbol, lat, lon, ambiguity, &(p->pos));
result_len = 1 + sizeof (p->pos);
/* Optional data extension. (singular) */
@ -622,6 +624,7 @@ int encode_position (int messaging, int compressed, double lat, double lon, int
* thyme - Time stamp or 0 for none.
* lat - Latitude.
* lon - Longitude.
* ambiguity - Number of digits to omit from location.
* symtab - Symbol table id or overlay.
* symbol - Symbol id.
*
@ -668,7 +671,7 @@ typedef struct aprs_object_s {
} u;
} aprs_object_t;
int encode_object (char *name, int compressed, time_t thyme, double lat, double lon,
int encode_object (char *name, int compressed, time_t thyme, double lat, double lon, int ambiguity,
char symtab, char symbol,
int power, int height, int gain, char *dir,
int course, int speed,
@ -721,7 +724,7 @@ int encode_object (char *name, int compressed, time_t thyme, double lat, double
result_len = sizeof(p->o) + sizeof (p->u.cpos);
}
else {
set_norm_position (symtab, symbol, lat, lon, &(p->u.pos));
set_norm_position (symtab, symbol, lat, lon, ambiguity, &(p->u.pos));
result_len = sizeof(p->o) + sizeof (p->u.pos);
/* Optional data extension. (singular) */
@ -784,7 +787,7 @@ int main (int argc, char *argv[])
/*********** Position ***********/
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), G_UNKNOWN, 'D', '&',
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), 0, G_UNKNOWN, 'D', '&',
0, 0, 0, NULL, G_UNKNOWN, 0, 0, 0, 0, NULL, result, sizeof(result));
dw_printf ("%s\n", result);
if (strcmp(result, "!4234.61ND07126.47W&") != 0) { dw_printf ("ERROR! line %d\n", __LINE__); errors++; }
@ -792,35 +795,35 @@ int main (int argc, char *argv[])
/* with PHG. */
// TODO: Need to test specifying some but not all.
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), G_UNKNOWN, 'D', '&',
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), 0, G_UNKNOWN, 'D', '&',
50, 100, 6, "N", G_UNKNOWN, 0, 0, 0, 0, NULL, result, sizeof(result));
dw_printf ("%s\n", result);
if (strcmp(result, "!4234.61ND07126.47W&PHG7368") != 0) { dw_printf ("ERROR! line %d\n", __LINE__); errors++; }
/* with freq. */
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), G_UNKNOWN, 'D', '&',
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), 0, G_UNKNOWN, 'D', '&',
0, 0, 0, NULL, G_UNKNOWN, 0, 146.955, 74.4, -0.6, NULL, result, sizeof(result));
dw_printf ("%s\n", result);
if (strcmp(result, "!4234.61ND07126.47W&146.955MHz T074 -060 ") != 0) { dw_printf ("ERROR! line %d\n", __LINE__); errors++; }
/* with course/speed, freq, and comment! */
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), G_UNKNOWN, 'D', '&',
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), 0, G_UNKNOWN, 'D', '&',
0, 0, 0, NULL, 180, 55, 146.955, 74.4, -0.6, "River flooding", result, sizeof(result));
dw_printf ("%s\n", result);
if (strcmp(result, "!4234.61ND07126.47W&180/055146.955MHz T074 -060 River flooding") != 0) { dw_printf ("ERROR! line %d\n", __LINE__); errors++; }
/* Course speed, no tone, + offset */
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), G_UNKNOWN, 'D', '&',
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), 0, G_UNKNOWN, 'D', '&',
0, 0, 0, NULL, 180, 55, 146.955, 0, 0.6, "River flooding", result, sizeof(result));
dw_printf ("%s\n", result);
if (strcmp(result, "!4234.61ND07126.47W&180/055146.955MHz Toff +060 River flooding") != 0) { dw_printf ("ERROR! line %d\n", __LINE__); errors++; }
/* Course speed, no tone, + offset + altitude */
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), 12345, 'D', '&',
encode_position (0, 0, 42+34.61/60, -(71+26.47/60), 0, 12345, 'D', '&',
0, 0, 0, NULL, 180, 55, 146.955, 0, 0.6, "River flooding", result, sizeof(result));
dw_printf ("%s\n", result);
if (strcmp(result, "!4234.61ND07126.47W&180/055146.955MHz Toff +060 /A=012345River flooding") != 0) { dw_printf ("ERROR! line %d\n", __LINE__); errors++; }
@ -829,7 +832,7 @@ int main (int argc, char *argv[])
/*********** Compressed position. ***********/
encode_position (0, 1, 42+34.61/60, -(71+26.47/60), G_UNKNOWN, 'D', '&',
encode_position (0, 1, 42+34.61/60, -(71+26.47/60), 0, G_UNKNOWN, 'D', '&',
0, 0, 0, NULL, G_UNKNOWN, 0, 0, 0, 0, NULL, result, sizeof(result));
dw_printf ("%s\n", result);
if (strcmp(result, "!D8yKC<Hn[& !") != 0) { dw_printf ("ERROR! line %d\n", __LINE__); errors++; }
@ -837,14 +840,14 @@ int main (int argc, char *argv[])
/* with PHG. In this case it is converted to precomputed radio range. TODO: check on this. Is 27.4 correct? */
encode_position (0, 1, 42+34.61/60, -(71+26.47/60), G_UNKNOWN, 'D', '&',
encode_position (0, 1, 42+34.61/60, -(71+26.47/60), 0, G_UNKNOWN, 'D', '&',
50, 100, 6, "N", G_UNKNOWN, 0, 0, 0, 0, NULL, result, sizeof(result));
dw_printf ("%s\n", result);
if (strcmp(result, "!D8yKC<Hn[&{CG") != 0) { dw_printf ("ERROR! line %d\n", __LINE__); errors++; }
/* with course/speed, freq, and comment! Roundoff. 55 knots should be 63 MPH. we get 62. */
encode_position (0, 1, 42+34.61/60, -(71+26.47/60), G_UNKNOWN, 'D', '&',
encode_position (0, 1, 42+34.61/60, -(71+26.47/60), 0, G_UNKNOWN, 'D', '&',
0, 0, 0, NULL, 180, 55, 146.955, 74.4, -0.6, "River flooding", result, sizeof(result));
dw_printf ("%s\n", result);
if (strcmp(result, "!D8yKC<Hn[&NUG146.955MHz T074 -060 River flooding") != 0) { dw_printf ("ERROR! line %d\n", __LINE__); errors++; }
@ -854,7 +857,7 @@ int main (int argc, char *argv[])
/*********** Object. ***********/
encode_object ("WB1GOF-C", 0, 0, 42+34.61/60, -(71+26.47/60), 'D', '&',
encode_object ("WB1GOF-C", 0, 0, 42+34.61/60, -(71+26.47/60), 0, 'D', '&',
0, 0, 0, NULL, G_UNKNOWN, 0, 0, 0, 0, NULL, result, sizeof(result));
dw_printf ("%s\n", result);
if (strcmp(result, ";WB1GOF-C *111111z4234.61ND07126.47W&") != 0) { dw_printf ("ERROR! line %d\n", __LINE__); errors++; }

View File

@ -1,5 +1,5 @@
int encode_position (int messaging, int compressed, double lat, double lon, int alt_ft,
int encode_position (int messaging, int compressed, double lat, double lon, int ambiguity, int alt_ft,
char symtab, char symbol,
int power, int height, int gain, char *dir,
int course, int speed_knots,
@ -7,7 +7,7 @@ int encode_position (int messaging, int compressed, double lat, double lon, int
char *comment,
char *presult, size_t result_size);
int encode_object (char *name, int compressed, time_t thyme, double lat, double lon,
int encode_object (char *name, int compressed, time_t thyme, double lat, double lon, int ambiguity,
char symtab, char symbol,
int power, int height, int gain, char *dir,
int course, int speed_knots,

View File

@ -539,7 +539,17 @@ static void pick_best_candidate (int chan)
/* Begining score depends on effort to get a valid frame CRC. */
candidate[chan][j][k].score = RETRY_MAX * 1000 - ((int)candidate[chan][j][k].retries * 1000);
if (candidate[chan][j][k].packet_p == NULL) {
candidate[chan][j][k].score = 0;
}
else {
/* Originally, this produced 0 for the PASSALL case. */
/* This didn't work so well when looking for the best score. */
/* Around 1.3 dev H, we add an extra 1 in here so the minimum */
/* score should now be 1 for anything received. */
candidate[chan][j][k].score = RETRY_MAX * 1000 - ((int)candidate[chan][j][k].retries * 1000) + 1;
}
}
/* Bump it up slightly if others nearby have the same CRC. */
@ -605,11 +615,15 @@ static void pick_best_candidate (int chan)
}
#endif
if (best_score == 0) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Unexpected internal problem, %s %d. How can best score be zero?\n", __FILE__, __LINE__);
}
/*
* send the best one along.
*/
/* Delete those not chosen. */
for (n = 0; n < num_bars; n++) {

5
ptt.c
View File

@ -162,6 +162,8 @@ void ptt_set_debug(int debug)
*
*------------------------------------------------------------------*/
#ifndef __WIN32__
void export_gpio(int gpio, int invert, int direction)
{
HANDLE fd;
@ -277,6 +279,9 @@ void export_gpio(int gpio, int invert, int direction)
close (fd);
}
#endif /* not __WIN32__ */
/*-------------------------------------------------------------------
*
* Name: ptt_init

128
tt_text.c
View File

@ -656,6 +656,71 @@ int tt_text_to_satsq (const char *text, int quiet, char *buttons, size_t buttons
/*------------------------------------------------------------------
*
* Name: tt_text_to_ascii2d
*
* Purpose: Convert text to the two digit per ascii character representation.
*
* Inputs: text - Input string.
* Any printable ASCII characters.
*
* quiet - True to suppress error messages.
*
* Outputs: buttons - Sequence of buttons to press.
*
* Returns: Number of errors detected.
*
* Description: The standard comment format uses the multipress
* encoding which allows only single case letters, digits,
* and the space character.
* This is a more flexible format that can handle all
* printable ASCII characters. We take the character code,
* subtract 32 and convert to two decimal digits. i.e.
* space = 00
* ! = 01
* " = 02
* ...
* ~ = 94
*
* This is mostly for internal use, so macros can generate
* comments with all characters.
*
*----------------------------------------------------------------*/
int tt_text_to_ascii2d (const char *text, int quiet, char *buttons)
{
const char *t = text;
char *b = buttons;
char c;
int errors = 0;
*b = '\0';
while ((c = *t++) != '\0') {
int n;
/* "isprint()" might depend on locale so use brute force. */
if (c < ' ' || c > '~') c = '?';
n = c - 32;
*b++ = (n / 10) + '0';
*b++ = (n % 10) + '0';
*b = '\0';
}
return (errors);
} /* end tt_text_to_ascii2d */
/*------------------------------------------------------------------
*
* Name: tt_multipress_to_text
@ -1282,6 +1347,69 @@ int tt_satsq_to_text (const char *buttons, int quiet, char *text)
} /* end tt_satsq_to_text */
/*------------------------------------------------------------------
*
* Name: tt_ascii2d_to_text
*
* Purpose: Convert the two digit ascii representation back to normal text.
*
* Inputs: buttons - Input string.
* Should contain pairs of digits in range 00 to 94.
*
* quiet - True to suppress error messages.
*
* Outputs: text - Converted to any printable ascii characters.
*
* Returns: Number of errors detected.
*
*----------------------------------------------------------------*/
int tt_ascii2d_to_text (const char *buttons, int quiet, char *text)
{
const char *b = buttons;
char *t = text;
char c1, c2;
int errors = 0;
*t = '\0';
while (*b != '\0') {
c1 = *b++;
if (*b != '\0') {
c2 = *b++;
}
else {
c2 = ' ';
}
if (isdigit(c1) && isdigit(c2)) {
int n;
n = (c1 - '0') * 10 + (c2 - '0');
*t++ = n + 32;
*t = '\0';
}
else {
/* Unexpected character. */
errors++;
if (! quiet) {
text_color_set (DW_COLOR_ERROR);
dw_printf ("ASCII2D to text: Invalid character pair \"%c%c\".\n", c1, c2);
}
}
}
return (errors);
} /* end tt_ascii2d_to_text */
/*------------------------------------------------------------------
*
* Name: tt_guess_type

View File

@ -14,6 +14,8 @@ int tt_text_to_mhead (const char *text, int quiet, char *buttons, size_t buttons
int tt_text_to_satsq (const char *text, int quiet, char *buttons, size_t buttonsiz);
int tt_text_to_ascii2d (const char *text, int quiet, char *buttons);
/* Decode DTMF to normal human readable form. */
@ -27,5 +29,8 @@ int tt_mhead_to_text (const char *buttons, int quiet, char *text, size_t textsiz
int tt_satsq_to_text (const char *buttons, int quiet, char *text);
int tt_ascii2d_to_text (const char *buttons, int quiet, char *text);
/* end tt_text.h */

View File

@ -136,6 +136,9 @@ static struct tt_user_s {
double latitude, longitude; /* Location either from user or generated */
/* position in the corral. */
int ambiguity; /* Number of digits to omit from location. */
/* Default 0, max. 4. */
char freq[12]; /* Frequency in format 999.999MHz */
char comment[MAX_COMMENT_LEN+1]; /* Free form comment from user. */
@ -381,7 +384,7 @@ static void digit_suffix (char *callsign, char *suffix)
char *t;
strlcpy (suffix, "000", sizeof(suffix));
strlcpy (suffix, "000", 5); // TODO: should have proper size
tt_text_to_two_key (callsign, 0, two_key);
for (t = two_key; *t != '\0'; t++) {
if (isdigit(*t)) {
@ -408,6 +411,7 @@ static void digit_suffix (char *callsign, char *suffix)
* loc_text - Original text for non lat/lon location
* latitude
* longitude
* ambiguity
* freq
* comment
* mic_e
@ -422,15 +426,14 @@ static void digit_suffix (char *callsign, char *suffix)
*----------------------------------------------------------------*/
int tt_user_heard (char *callsign, int ssid, char overlay, char symbol, char *loc_text, double latitude,
double longitude, char *freq, char *comment, char mic_e, char *dao)
double longitude, int ambiguity, char *freq, char *comment, char mic_e, char *dao)
{
int i;
// TODO: remove debug
text_color_set(DW_COLOR_DEBUG);
dw_printf ("tt_user_heard (%s, %d, %c, %c, %s, ...)\n", callsign, ssid, overlay, symbol, loc_text);
//text_color_set(DW_COLOR_DEBUG);
//dw_printf ("tt_user_heard (%s, %d, %c, %c, %s, ...)\n", callsign, ssid, overlay, symbol, loc_text);
/*
* At this time all messages are expected to contain a callsign.
@ -475,6 +478,8 @@ int tt_user_heard (char *callsign, int ssid, char overlay, char symbol, char *lo
tt_user[i].corral_slot = corral_slot();
}
tt_user[i].ambiguity = ambiguity;
strlcpy (tt_user[i].freq, freq, sizeof(tt_user[i].freq));
strncpy (tt_user[i].comment, comment, MAX_COMMENT_LEN);
tt_user[i].comment[MAX_COMMENT_LEN] = '\0';
@ -502,6 +507,10 @@ int tt_user_heard (char *callsign, int ssid, char overlay, char symbol, char *lo
tt_user[i].longitude = longitude;
}
if (ambiguity != G_UNKNOWN) {
tt_user[i].ambiguity = ambiguity;
}
if (freq[0] != '\0') {
strlcpy (tt_user[i].freq, freq, sizeof(tt_user[i].freq));
}
@ -653,6 +662,7 @@ static void xmit_object_report (int i, int first_time)
char stemp[300]; // src>dest,path:object_info
double olat, olong;
int oambig; // Position ambiguity.
packet_t pp;
char c4[4];
@ -680,6 +690,8 @@ static void xmit_object_report (int i, int first_time)
*/
olat = tt_user[i].latitude;
olong = tt_user[i].longitude;
oambig = tt_user[i].ambiguity;
if (oambig == G_UNKNOWN) oambig = 0;
}
else {
/*
@ -691,6 +703,7 @@ static void xmit_object_report (int i, int first_time)
olat = c_lat - (tt_user[i].corral_slot - 1) * c_offs;
olong = c_long;
oambig = 0;
}
/*
@ -766,7 +779,7 @@ static void xmit_object_report (int i, int first_time)
strlcat (stemp, ":", sizeof(stemp));
encode_object (object_name, 0, tt_user[i].last_heard, olat, olong,
encode_object (object_name, 0, tt_user[i].last_heard, olat, olong, oambig,
tt_user[i].overlay, tt_user[i].symbol,
0,0,0,NULL, G_UNKNOWN, G_UNKNOWN, /* PHGD, Course/Speed */
atof(tt_user[i].freq), 0, 0, info_comment, object_info, sizeof(object_info));

View File

@ -7,7 +7,7 @@
void tt_user_init (struct audio_s *p_audio_config, struct tt_config_s *p);
int tt_user_heard (char *callsign, int ssid, char overlay, char symbol, char *loc_text, double latitude,
double longitude, char *freq, char *comment, char mic_e, char *dao);
double longitude, int ambiguity, char *freq, char *comment, char mic_e, char *dao);
void tt_user_background (void);
void tt_user_dump (void);