Time stamps and documentation for kissutil.

This commit is contained in:
wb2osz 2017-09-30 13:41:58 -04:00
parent 6e34b5f472
commit c904b57d1d
15 changed files with 304 additions and 47 deletions

View File

@ -432,7 +432,7 @@ aclients : aclients.c ax25_pad.c fcs_calc.c textcolor.o misc.a
# Note: kiss_frame.c has conditional compilation on KISSUTIL.
kissutil : kissutil.c kiss_frame.c ax25_pad.o fcs_calc.o textcolor.o serial_port.o dtime_now.o sock.o misc.a
$(CC) $(CFLAGS) -g -DKISSUTIL -o $@ $^
$(CC) $(CFLAGS) -g -DKISSUTIL -o $@ $^ $(LDFLAGS)
# Touch Tone to Speech sample application.
@ -637,6 +637,7 @@ install : $(APPS) direwolf.conf tocalls.txt symbols-new.txt symbolsX.txt dw-icon
$(INSTALL) -D --mode=644 man1/decode_aprs.1 $(INSTALLDIR)/man/man1/decode_aprs.1
$(INSTALL) -D --mode=644 man1/direwolf.1 $(INSTALLDIR)/man/man1/direwolf.1
$(INSTALL) -D --mode=644 man1/gen_packets.1 $(INSTALLDIR)/man/man1/gen_packets.1
$(INSTALL) -D --mode=644 man1/kissutil.1 $(INSTALLDIR)/man/man1/kissutil.1
$(INSTALL) -D --mode=644 man1/ll2utm.1 $(INSTALLDIR)/man/man1/ll2utm.1
$(INSTALL) -D --mode=644 man1/log2gpx.1 $(INSTALLDIR)/man/man1/log2gpx.1
$(INSTALL) -D --mode=644 man1/text2tt.1 $(INSTALLDIR)/man/man1/text2tt.1

View File

@ -430,9 +430,9 @@ install-conf : direwolf.conf
# Separate application to decode raw data.
# First two use .c rather than .o because they depend on DECAMAIN definition.
# First three use .c rather than .o because they depend on DECAMAIN definition.
decode_aprs : decode_aprs.c kiss_frame.c dwgpsnmea.o dwgps.o dwgpsd.o serial_port.o symbols.o ax25_pad.o textcolor.o fcs_calc.o latlong.o log.o telemetry.o tt_text.o
decode_aprs : decode_aprs.c kiss_frame.c ax25_pad.c dwgpsnmea.o dwgps.o dwgpsd.o serial_port.o symbols.o textcolor.o fcs_calc.o latlong.o log.o telemetry.o tt_text.o
$(CC) $(CFLAGS) -DDECAMAIN -o $@ $^ -lm
# Convert between text and touch tone representation.

Binary file not shown.

View File

@ -1,5 +1,8 @@
#include "direwolf.h"
#include <stdio.h>
#include "textcolor.h"
#include "dtime_now.h"
@ -18,7 +21,25 @@
#endif
/*------------------------------------------------------------------
*
* Name: dtime_now
*
* Purpose: Return current time as double precision.
*
* Input: none
*
* Returns: Unix time, as double precision, so we can get resolution
* finer than one second.
*
* Description: Normal unix time is in seconds since 1/1/1970 00:00:00 UTC.
* Sometimes we want resolution finer than a second.
* Rather than having a separate variable for the fractional
* part of a second, and having extra calculations everywhere,
* simply use double precision floating point to make usage
* easier.
*
*---------------------------------------------------------------*/
double dtime_now (void)
@ -59,3 +80,148 @@ double dtime_now (void)
return (result);
}
#if __WIN32__
/*
* Windows doesn't have localtime_r.
* It should have the equivalent localtime_s, with opposite parameter
* order, but I get undefined reference when trying to use it.
*/
static struct tm *localtime_r(time_t *clock, struct tm *res)
{
struct tm *tm;
tm = localtime (clock);
memcpy (res, tm, sizeof(struct tm));
return (res);
}
#endif
/*------------------------------------------------------------------
*
* Name: timestamp_now
*
* Purpose: Convert local time to one of these formats for debug output.
*
* HH:MM:SS
* HH:MM:SS.mmm
*
* Input: result_size - Size of result location.
* Should be at least 9 or 13.
*
* show_ms - True to display milliseconds.
*
* Output: result - Result is placed here.
*
*---------------------------------------------------------------*/
void timestamp_now (char *result, int result_size, int show_ms)
{
double now = dtime_now();
time_t t = (int)now;
struct tm tm;
localtime_r (&t, &tm);
strftime (result, result_size, "%H:%M:%S", &tm);
if (show_ms) {
int ms = (now - (int)t) * 1000;
char strms[16];
if (ms == 1000) ms = 999;
sprintf (strms, ".%03d", ms);
strlcat (result, strms, result_size);
}
} /* end timestamp_now */
/*------------------------------------------------------------------
*
* Name: timestamp_user_format
*
* Purpose: Convert local time user-specified format. e.g.
*
* HH:MM:SS
* mm/dd/YYYY HH:MM:SS
* dd/mm/YYYY HH:MM:SS
*
* Input: result_size - Size of result location.
*
* user_format - See strftime documentation.
*
* https://linux.die.net/man/3/strftime
* https://msdn.microsoft.com/en-us/library/aa272978(v=vs.60).aspx
*
* Note that Windows does not support all of the Linux formats.
* For example, Linux has %T which is equivalent to %H:%M:%S
*
* Output: result - Result is placed here.
*
*---------------------------------------------------------------*/
void timestamp_user_format (char *result, int result_size, char *user_format)
{
double now = dtime_now();
time_t t = (int)now;
struct tm tm;
localtime_r (&t, &tm);
strftime (result, result_size, user_format, &tm);
} /* end timestamp_user_format */
/*------------------------------------------------------------------
*
* Name: timestamp_filename
*
* Purpose: Generate unique file name based on the current time.
* The format will be:
*
* YYYYMMDD-HHMMSS-mmm
*
* Input: result_size - Size of result location.
* Should be at least 20.
*
* Output: result - Result is placed here.
*
* Description: This is for the kissutil "-r" option which places
* each received frame in a new file. It is possible to
* have two packets arrive in less than a second so we
* need more than one second resolution.
*
* What if someone wants UTC, rather than local time?
* You can simply set an environment variable like this:
*
* TZ=UTC direwolf
*
* so it's probably not worth the effort to add another
* option.
*
*---------------------------------------------------------------*/
void timestamp_filename (char *result, int result_size)
{
double now = dtime_now();
time_t t = (int)now;
struct tm tm;
localtime_r (&t, &tm);
strftime (result, result_size, "%Y%m%d-%H%M%S", &tm);
int ms = (now - (int)t) * 1000;
char strms[16];
if (ms == 1000) ms = 999;
sprintf (strms, "-%03d", ms);
strlcat (result, strms, result_size);
} /* end timestamp_filename */

View File

@ -1,3 +1,9 @@
extern double dtime_now (void);
extern double dtime_now (void);
void timestamp_now (char *result, int result_size, int show_ms);
void timestamp_user_format (char *result, int result_size, char *user_format);
void timestamp_filename (char *result, int result_size);

View File

@ -35,8 +35,6 @@
* See the "usage" functions at the bottom for details.
*
* FIXME: This is a rough prototype that needs more work.
* TODO: Prepare the "man" page.
* TODO: Add to User Guide.
*
*---------------------------------------------------------------*/
@ -137,16 +135,20 @@ static int serial_speed = 9600; /* -s option. */
static int verbose = 0; /* -v option. */
/* Display the KISS protocol in hexadecimal for troubleshooting. */
static char transmit_queue[120] = ""; /* -t option */
static char transmit_from[120] = ""; /* -f option */
/* When specified, files are read from this directory */
/* rather than using stdin. Each file is one or more */
/* lines in the standard monitoring format. */
static char receive_queue[120] = ""; /* -r option */
static char receive_output[120] = ""; /* -o option */
/* When specified, each received frame is stored as a file */
/* with a unique name here. */
/* Directory must already exist; we won't create it. */
static char timestamp_format[60] = ""; /* -T option */
/* Precede received frames with timestamp. */
/* Command line option uses "strftime" format string. */
#if __WIN32__
#define THREAD_F unsigned __stdcall
@ -213,7 +215,7 @@ int main (int argc, char *argv[])
/* ':' following option character means arg is required. */
c = getopt_long(argc, argv, "h:p:s:vt:r:",
c = getopt_long(argc, argv, "h:p:s:vf:o:T:",
long_options, &option_index);
if (c == -1)
break;
@ -236,12 +238,16 @@ int main (int argc, char *argv[])
verbose++;
break;
case 't': /* -t for transmit queue directory. */
strlcpy (transmit_queue, optarg, sizeof(transmit_queue));
case 'f': /* -f for transmit files directory. */
strlcpy (transmit_from, optarg, sizeof(transmit_from));
break;
case 'r': /* -t for receive queue directory. */
strlcpy (receive_queue, optarg, sizeof(receive_queue));
case 'o': /* -o for receive output directory. */
strlcpy (receive_output, optarg, sizeof(receive_output));
break;
case 'T': /* -T for receive timestamp. */
strlcpy (timestamp_format, optarg, sizeof(timestamp_format));
break;
case '?':
@ -265,9 +271,9 @@ int main (int argc, char *argv[])
/*
* If receive queue directory was specified, make sure that it exists.
*/
if (strlen(receive_queue) > 0) {
if (strlen(receive_output) > 0) {
// TODO
}
/* If port begins with digit, consider it to be TCP. */
@ -304,7 +310,7 @@ int main (int argc, char *argv[])
*/
char stuff[1000];
if (strlen(transmit_queue) > 0) {
if (strlen(transmit_from) > 0) {
/*
* Process and delete all files in specified directory.
* When done, sleep for a second and try again.
@ -318,7 +324,7 @@ int main (int argc, char *argv[])
//text_color_set(DW_COLOR_DEBUG);
//dw_printf("Get directory listing...\n");
dp = opendir (transmit_queue);
dp = opendir (transmit_from);
if (dp != NULL) {
while ((ep = readdir(dp)) != NULL) {
char path [300];
@ -328,7 +334,7 @@ int main (int argc, char *argv[])
text_color_set(DW_COLOR_DEBUG);
dw_printf ("Processing %s for transmit...\n", ep->d_name);
strlcpy (path, transmit_queue, sizeof(path));
strlcpy (path, transmit_from, sizeof(path));
strlcat (path, DIR_CHAR, sizeof(path));
strlcat (path, ep->d_name, sizeof(path));
fp = fopen (path, "r");
@ -352,7 +358,7 @@ int main (int argc, char *argv[])
}
else {
text_color_set(DW_COLOR_ERROR);
dw_printf("Can't access transmit queue directory %s. Quitting.\n", transmit_queue);
dw_printf("Can't access transmit queue directory %s. Quitting.\n", transmit_from);
exit (EXIT_FAILURE);
}
SLEEP_SEC (1);
@ -367,6 +373,8 @@ int main (int argc, char *argv[])
}
}
return (EXIT_SUCCESS);
} /* end main */
@ -572,6 +580,9 @@ static THREAD_F tnc_listen_net (void *arg)
/*
* Connect to network KISS TNC.
*/
// For the IGate we would loop around and try to reconnect if the TNC
// goes away. We should probably do the same here.
server_sock = sock_connect (hostname, port, "TCP KISS TNC", allow_ipv6, debug, ipaddr_str);
if (server_sock == -1) {
@ -609,9 +620,6 @@ static THREAD_F tnc_listen_net (void *arg)
dw_printf ("Read error from TCP KISS TNC. Terminating.\n");
exit (EXIT_FAILURE);
// For the IGate we would loop around and try to reconnect but
// it doesn't seem appropriate here. Just quit.
} /* end tnc_listen_net */
@ -711,21 +719,29 @@ void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int cli
printf ("ERROR - Invalid KISS data frame from TNC.\n");
}
else {
char addrs[500];
char prefix[100]; // Channel and optional timestamp.
// Like [0] or [2 12:34:56]
char addrs[AX25_MAX_ADDRS*AX25_MAX_ADDR_LEN]; // Like source>dest,digi,...,digi:
unsigned char *pinfo;
int info_len;
if (strlen(timestamp_format) > 0) {
char ts[100];
timestamp_user_format (ts, sizeof(ts), timestamp_format);
snprintf (prefix, sizeof(prefix), "[%d %s]", chan, ts);
}
else {
snprintf (prefix, sizeof(prefix), "[%d]", chan);
}
ax25_format_addrs (pp, addrs);
info_len = ax25_get_info (pp, &pinfo);
text_color_set(DW_COLOR_REC);
if (chan != 0) {
dw_printf ("[%d] ", chan);
}
dw_printf ("%s", addrs); /* stations followed by : */
dw_printf ("%s %s", prefix, addrs); // [channel] Addresses followed by :
// Safe print will replace any unprintable characters with
// hexadecimal representation.
@ -735,24 +751,27 @@ void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int cli
/*
* Add to receive queue directory if specified.
* File name will be based on time to 0.01 sec resolution. ??? TBD
* File name will be based on current local time.
* If you want UTC, just set an environment variable like this:
*
* TZ=UTC kissutil ...
*/
if (strlen(receive_queue) > 0) {
if (strlen(receive_output) > 0) {
char fname [30];
char path [300];
FILE *fp;
snprintf (fname, sizeof(fname), "%.0f", dtime_now() * 100.);
timestamp_filename (fname, (int)sizeof(fname));
strlcpy (path, receive_queue, sizeof(path));
strlcpy (path, receive_output, sizeof(path));
strlcat (path, DIR_CHAR, sizeof(path));
strlcat (path, fname, sizeof(path));
text_color_set(DW_COLOR_DEBUG);
dw_printf ("save received frame to %s\n", path);
dw_printf ("Save received frame to %s\n", path);
fp = fopen (path, "w");
if (fp != NULL) {
fprintf (fp, "%s%s\n", addrs, pinfo);
fprintf (fp, "%s %s%s\n", prefix, addrs, pinfo);
fclose (fp);
}
else {
@ -769,10 +788,14 @@ void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int cli
kiss_msg[kiss_len] = '\0';
text_color_set(DW_COLOR_REC);
// TODO: Just precede by "h " for in/out symmetry?
printf ("KISS protocol set hardware \"%s\", channel %d\n", (char*)(kiss_msg+1), chan);
// Display as "h ..." for in/out symmetry.
// Use safe print here?
dw_printf ("[%d] h %s\n", chan, (char*)(kiss_msg+1));
break;
/*
* The rest should only go TO the TNC and not come FROM it.
*/
case KISS_CMD_TXDELAY: /* 1 = TXDELAY */
case KISS_CMD_PERSISTENCE: /* 2 = Persistence */
case KISS_CMD_SLOTTIME: /* 3 = SlotTime */
@ -833,8 +856,9 @@ static void usage(void)
dw_printf (" a serial port. e.g. /dev/ttyAMA0 or COM3.\n");
dw_printf (" -s Serial port speed, default 9600.\n");
dw_printf (" -v Verbose. Show the KISS frame contents.\n");
dw_printf (" -t Transmit queue directory. Processs and delete files here.\n");
dw_printf (" -r Receive queue directory. Store received frames here.\n");
dw_printf (" -f Transmit files directory. Processs and delete files here.\n");
dw_printf (" -o Receive output queue directory. Store received frames here.\n");
dw_printf (" -T Precede received frames with 'strftime' format time stamp.\n");
usage2();
exit (EXIT_SUCCESS);
}

View File

@ -48,5 +48,5 @@ of how to set up tests and the results.
.SH SEE ALSO
More detailed information is in the pdf files in /usr/local/share/doc/direwolf, or possibly /usr/share/doc/direwolf, depending on installation location.
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, ll2utm, log2gpx, text2tt, tt2text, utm2ll
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, kissutil, ll2utm, log2gpx, text2tt, tt2text, utm2ll

View File

@ -87,5 +87,5 @@ Try different combinations of options to find the best decoding performance.
.SH SEE ALSO
More detailed information is in the pdf files in /usr/local/share/doc/direwolf, or possibly /usr/share/doc/direwolf, depending on installation location.
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, ll2utm, log2gpx, text2tt, tt2text, utm2ll
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, kissutil, ll2utm, log2gpx, text2tt, tt2text, utm2ll

View File

@ -152,5 +152,5 @@ rtl_fm \-f 144.39M \-o 4 \- | direwolf \-n 1 \-r 24000 \-b 16 \-
.SH SEE ALSO
More detailed information is in the pdf files in /usr/local/share/doc/direwolf, or possibly /usr/share/doc/direwolf, depending on installation location.
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, ll2utm, log2gpx, text2tt, tt2text, utm2ll
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, kissutil, ll2utm, log2gpx, text2tt, tt2text, utm2ll

60
man1/kissutil.1 Normal file
View File

@ -0,0 +1,60 @@
.TH KISSUTIL 1
.SH NAME
kissutil \- KISS TNC troubleshooting and Application Interface.
.SH SYNOPSIS
.B kissutil
[ \fIoptions\fR ]
.SH DESCRIPTION
\fBkissutil\fR can be used interactively for troubleshooting a KISS TNC.
It is usable with direwolf and other generic KISS TNCs connected to a serial port.
It can also be used as an application interface where each side places files in a
directory for the other to process.
See User Guide for more details.
.SH OPTIONS
.TP
.BI "-h " "host"
Hostname or IP address for a TCP KISS TNC. Default is localhost.
.TP
.BI "-p " "port"
A number may be specified for a TCP port other than the default 8001.
If not a number, it is considered to be a serial port name such as /dev/ttyS0 or COM3.
.TP
.BI "-s " "speed"
Speed for serial port. e.g. 9600.
.TP
.BI "-o " "rec-directory"
For each received frame, a new file is created here.
It is expected that some other application will process files in this directory then delete them.
.TP
.BI "-T " "format"
Each received frame will be preceded by a timestamp in the specified format.
See strftime documentation for a description of the format string.
Example: %H:%M:%S for current time in hours, minutes, seconds.
.TP
.BI "-f " "xmit-directory"
Files in this directory are transmited and deleted.
Another application places a file here when it wants something to be transmitted.
.TP
.BI "-v "
Verbose - Display the KISS frames going to and from the TNC.
.SH SEE ALSO
More detailed information is in the pdf files in /usr/local/share/doc/direwolf, or possibly /usr/share/doc/direwolf, depending on installation location.
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, kissutil, ll2utm, log2gpx, text2tt, tt2text, utm2ll

View File

@ -30,5 +30,5 @@ zone = 19T, easting = 307504, northing = 4721177
.SH SEE ALSO
More detailed information is in the pdf files in /usr/local/share/doc/direwolf, or possibly /usr/share/doc/direwolf, depending on installation location.
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, ll2utm, log2gpx, text2tt, tt2text, utm2ll
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, kissutil, ll2utm, log2gpx, text2tt, tt2text, utm2ll

View File

@ -36,5 +36,5 @@ None.
.SH SEE ALSO
More detailed information is in the pdf files in /usr/local/share/doc/direwolf, or possibly /usr/share/doc/direwolf, depending on installation location.
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, ll2utm, log2gpx, text2tt, tt2text, utm2ll
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, kissutil, ll2utm, log2gpx, text2tt, tt2text, utm2ll

View File

@ -60,5 +60,5 @@ Push buttons for two-key method:
.SH SEE ALSO
More detailed information is in the pdf files in /usr/local/share/doc/direwolf, or possibly /usr/share/doc/direwolf, depending on installation location.
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, ll2utm, log2gpx, text2tt, tt2text, utm2ll
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, kissutil, ll2utm, log2gpx, text2tt, tt2text, utm2ll

View File

@ -62,5 +62,5 @@ Decoded text from two-key method:
.SH SEE ALSO
More detailed information is in the pdf files in /usr/local/share/doc/direwolf, or possibly /usr/share/doc/direwolf, depending on installation location.
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, ll2utm, log2gpx, text2tt, tt2text, utm2ll
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, kissutil, ll2utm, log2gpx, text2tt, tt2text, utm2ll

View File

@ -36,5 +36,5 @@ latitude = 42.662139, longitude = -71.365553
.SH SEE ALSO
More detailed information is in the pdf files in /usr/local/share/doc/direwolf, or possibly /usr/share/doc/direwolf, depending on installation location.
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, ll2utm, log2gpx, text2tt, tt2text, utm2ll
Applications in this package: aclients, atest, decode_aprs, direwolf, gen_packets, kissutil, ll2utm, log2gpx, text2tt, tt2text, utm2ll