From 8ac14f86f5ee43176423fbdb07fe65aa18fcdb81 Mon Sep 17 00:00:00 2001
From: wb2osz <wb2osz@comcast.net>
Date: Sat, 7 Nov 2020 18:12:46 -0500
Subject: [PATCH 1/2] Mention cmake scripts contributor.

---
 CHANGES.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGES.md b/CHANGES.md
index 5097db7d..4196f7dd 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -8,7 +8,7 @@
 ### New Build Procedure: ###
 
 
-- Rather than trying to keep a bunch of different platform specific Makefiles in sync, "cmake" is now used for greater portability and easier maintenance.
+- Rather than trying to keep a bunch of different platform specific Makefiles in sync, "cmake" is now used for greater portability and easier maintenance.  This was contributed by Davide Gerhard.
 
 - README.md has a quick summary of the process.  More details in the ***User Guide***.
 

From f8c221e579e631d18b3e8028ee08ccc7d2499618 Mon Sep 17 00:00:00 2001
From: Thomas Habets <thomas@habet.se>
Date: Thu, 23 Apr 2020 16:24:20 +0100
Subject: [PATCH 2/2] Add option -m to decode to metric

This enables the natural unit for 96% of the world's population.
---
 src/atest.c       |  2 +-
 src/decode_aprs.c | 22 ++++++++++++++++------
 src/decode_aprs.h |  4 +++-
 src/direwolf.c    | 10 ++++++++--
 src/direwolf.h    |  1 +
 src/pfilter.c     |  3 ++-
 6 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/src/atest.c b/src/atest.c
index 5c197759..19103cff 100644
--- a/src/atest.c
+++ b/src/atest.c
@@ -880,7 +880,7 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev
 
 	  decode_aprs_t A;
 
-	  decode_aprs (&A, pp, 0);
+	  decode_aprs (&A, pp, 0, 0);
 
 	  // Temp experiment to see how different systems set the RR bits in the source and destination.
 	  // log_rr_bits (&A, pp);
diff --git a/src/decode_aprs.c b/src/decode_aprs.c
index 3afa3773..aea38fa3 100644
--- a/src/decode_aprs.c
+++ b/src/decode_aprs.c
@@ -152,7 +152,7 @@ static void process_comment (decode_aprs_t *A, char *pstart, int clen);
  *
  *------------------------------------------------------------------*/
 
-void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet)
+void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, int metric)
 {
 
 	char dest[AX25_MAX_ADDR_LEN];
@@ -165,6 +165,7 @@ void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet)
 	memset (A, 0, sizeof (*A));
 
 	A->g_quiet = quiet;
+	A->g_metric = metric;
 
 	if (isprint(*pinfo)) {
 	  snprintf (A->g_msg_type, sizeof(A->g_msg_type), "Unknown APRS Data Type Indicator \"%c\"", *pinfo);
@@ -542,7 +543,11 @@ void decode_aprs_print (decode_aprs_t *A) {
 	  char spd[20];
 
 	  if (strlen(stemp) > 0) strlcat (stemp, ", ", sizeof(stemp));
-	  snprintf (spd, sizeof(spd), "%.0f MPH", A->g_speed_mph);
+	  if (A->g_metric) {
+	    snprintf (spd, sizeof(spd), "%.0f km/h", DW_MILES_TO_KM(A->g_speed_mph));
+	  } else {
+	    snprintf (spd, sizeof(spd), "%.0f MPH", A->g_speed_mph);
+	  }
 	  strlcat (stemp, spd, sizeof(stemp));
 	};
 
@@ -558,7 +563,11 @@ void decode_aprs_print (decode_aprs_t *A) {
 	  char alt[20];
 
 	  if (strlen(stemp) > 0) strlcat (stemp, ", ", sizeof(stemp));
-	  snprintf (alt, sizeof(alt), "alt %.0f ft", A->g_altitude_ft);
+	  if (A->g_metric) {
+	    snprintf (alt, sizeof(alt), "alt %.0f m", DW_FEET_TO_METERS(A->g_altitude_ft));
+	  } else {
+	    snprintf (alt, sizeof(alt), "alt %.0f ft", A->g_altitude_ft);
+	  }
 	  strlcat (stemp, alt, sizeof(stemp));
 	};
 
@@ -4780,6 +4789,7 @@ int main (int argc, char *argv[])
 	int num_bytes;
 	char *p;	
 	packet_t pp;
+	int metric = 0;
 
 #if __WIN32__
 
@@ -4941,7 +4951,7 @@ int main (int argc, char *argv[])
 	        ax25_safe_print ((char *)pinfo, info_len, 1);	// Display non-ASCII to hexadecimal.
 	        dw_printf ("\n");
 
-	        decode_aprs (&A, pp, 0);			// Extract information into structure.
+	        decode_aprs (&A, pp, 0, metric);		// Extract information into structure.
 
 	        decode_aprs_print (&A);			// Now print it in human readable format.
 
@@ -4962,9 +4972,9 @@ int main (int argc, char *argv[])
 	      if (pp != NULL) {
 	        decode_aprs_t A;
 
-	        decode_aprs (&A, pp, 0);	// Extract information into structure.
+	        decode_aprs (&A, pp, 0, metric);	// Extract information into structure.
 
-	        decode_aprs_print (&A);		// Now print it in human readable format.
+	        decode_aprs_print (&A);			// Now print it in human readable format.
 
 	        // This seems to be redundant because we used strict option
 	        // when parsing the monitoring format text.
diff --git a/src/decode_aprs.h b/src/decode_aprs.h
index cdbb1678..6ca3ded4 100644
--- a/src/decode_aprs.h
+++ b/src/decode_aprs.h
@@ -24,6 +24,8 @@ typedef struct decode_aprs_s {
 
 	int g_quiet;			/* Suppress error messages when decoding. */
 
+	int g_metric;			/* Print metric instead of US customary units */
+
         char g_src[AX25_MAX_ADDR_LEN];
 
         char g_msg_type[60];		/* APRS data type.  Telemetry descriptions get pretty long. */
@@ -135,7 +137,7 @@ typedef struct decode_aprs_s {
 
 
 
-extern void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet);
+extern void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, int metric);
 
 extern void decode_aprs_print (decode_aprs_t *A);
 
diff --git a/src/direwolf.c b/src/direwolf.c
index 456b16f0..a56fac32 100644
--- a/src/direwolf.c
+++ b/src/direwolf.c
@@ -183,6 +183,7 @@ static int d_p_opt = 0;			/* "-d p" option for dumping packets over radio. */
 
 static int q_h_opt = 0;			/* "-q h" Quiet, suppress the "heard" line with audio level. */
 static int q_d_opt = 0;			/* "-q d" Quiet, suppress the printing of decoded of APRS packets. */
+static int m_opt = 0;			/* "-m" for metric output. */
 
 static int A_opt_ais_to_obj = 0;	/* "-A" Convert received AIS to APRS "Object Report." */
 
@@ -387,7 +388,7 @@ int main (int argc, char *argv[])
 
 	  /* ':' following option character means arg is required. */
 
-          c = getopt_long(argc, argv, "hP:B:gjJD:U:c:pxr:b:n:d:q:t:ul:L:Sa:E:T:e:X:A",
+          c = getopt_long(argc, argv, "hP:B:gjJD:U:c:pxr:b:mn:d:q:t:ul:L:Sa:E:T:e:X:A",
                         long_options, &option_index);
           if (c == -1)
             break;
@@ -505,6 +506,10 @@ int main (int argc, char *argv[])
    	    }
             break;
 
+	  case 'm':				/* -m set metric */
+	    m_opt = 1;
+	    break;
+
           case 'n':				/* -n number of audio channels for first audio device.  1 or 2. */
 	 
 	    n_opt = atoi(optarg);
@@ -1247,7 +1252,7 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
 	  // we still want to decode it for logging and other processing.
 	  // Just be quiet about errors if "-qd" is set.
 
-	  decode_aprs (&A, pp, q_d_opt);
+	  decode_aprs (&A, pp, q_d_opt, m_opt);
 
 	  if ( ! q_d_opt ) {
 
@@ -1453,6 +1458,7 @@ static void usage (char **argv)
 	dw_printf ("    -c fname       Configuration file name.\n");
 	dw_printf ("    -l logdir      Directory name for log files.  Use . for current.\n");
 	dw_printf ("    -r n           Audio sample rate, per sec.\n");
+	dw_printf ("    -m             Use metric instead of US customary units.\n");
 	dw_printf ("    -n n           Number of audio channels, 1 or 2.\n");
 	dw_printf ("    -b n           Bits per audio sample, 8 or 16.\n");
 	dw_printf ("    -B n           Data rate in bits/sec for channel 0.  Standard values are 300, 1200, 2400, 4800, 9600.\n");
diff --git a/src/direwolf.h b/src/direwolf.h
index efc329ba..8e34a888 100644
--- a/src/direwolf.h
+++ b/src/direwolf.h
@@ -176,6 +176,7 @@
 #define DW_METERS_TO_FEET(x) ((x) == G_UNKNOWN ? G_UNKNOWN : (x) * 3.2808399)
 #define DW_FEET_TO_METERS(x) ((x) == G_UNKNOWN ? G_UNKNOWN : (x) * 0.3048)
 #define DW_KM_TO_MILES(x) ((x) == G_UNKNOWN ? G_UNKNOWN : (x) * 0.621371192)
+#define DW_MILES_TO_KM(x) ((x) == G_UNKNOWN ? G_UNKNOWN : (x) * 1.609344)
 
 #define DW_KNOTS_TO_MPH(x) ((x) == G_UNKNOWN ? G_UNKNOWN : (x) * 1.15077945)
 #define DW_KNOTS_TO_METERS_PER_SEC(x) ((x) == G_UNKNOWN ? G_UNKNOWN : (x) * 0.51444444444)
diff --git a/src/pfilter.c b/src/pfilter.c
index 626f0712..a3e097c3 100644
--- a/src/pfilter.c
+++ b/src/pfilter.c
@@ -200,6 +200,7 @@ int pfilter (int from_chan, int to_chan, char *filter, packet_t pp, int is_aprs)
 	pfstate_t pfstate;
 	char *p;
 	int result;
+	int metric = 0;
 
 	assert (from_chan >= 0 && from_chan <= MAX_CHANS);
 	assert (to_chan >= 0 && to_chan <= MAX_CHANS);
@@ -235,7 +236,7 @@ int pfilter (int from_chan, int to_chan, char *filter, packet_t pp, int is_aprs)
 	pfstate.is_aprs = is_aprs;
 
 	if (is_aprs) {
-	  decode_aprs (&pfstate.decoded, pp, 1);
+	  decode_aprs (&pfstate.decoded, pp, 1, metric);
 	}
 
 	next_token(&pfstate);