[ntpsec commit] Forward-port patches for NTP Classic [Bug 2859]...
Eric S. Raymond
esr at ntpsec.org
Thu Oct 22 18:34:46 UTC 2015
Module: ntpsec
Branch: master
Commit: 14d6f208a21a2f9402f8c90ac299be21df60b5bd
Changeset: http://git.ntpsec.org/ntpsec/commit/?id=14d6f208a21a2f9402f8c90ac299be21df60b5bd
Author: Eric S. Raymond <esr at thyrsus.com>
Date: Thu Oct 22 14:33:29 2015 -0400
Forward-port patches for NTP Classic [Bug 2859]...
...Improve raw DCF77 robustness decoding, from Frank Kardel
---
NEWS | 2 +
include/parse.h | 6 +--
libparse/clk_meinberg.c | 4 +-
libparse/clk_rawdcf.c | 99 +++++++++++++++++++++++++++++++++++++++++++------
libparse/clk_schmid.c | 4 +-
libparse/parse.c | 8 +---
ntpd/refclock_parse.c | 8 ++--
7 files changed, 102 insertions(+), 29 deletions(-)
diff --git a/NEWS b/NEWS
index 7ae3833..3193d4e 100644
--- a/NEWS
+++ b/NEWS
@@ -12,7 +12,9 @@ on user-visible changes.
robust, and require 2 consecutive timestamps to be consistent.
* [Bug 2845] Harden memory allocation in ntpd; implement and
use 'eallocarray(...)' where appropriate.
+* [Bug 2846] Report 'unsynchronized' status during the leap second.
* [Bug 2855] Implement conditional leap smear feature; includes
later fixes for parser support and reporting leap smear in the REFID.
+* [Bug 2859] Improve raw DCF77 robustness decoding. Frank Kardel.
// end
diff --git a/include/parse.h b/include/parse.h
index ba2bd0e..afedeef 100644
--- a/include/parse.h
+++ b/include/parse.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1989-2005 by Frank Kardel <kardel at ntp.org>
+ * Copyright (c) 1989-2015 by Frank Kardel <kardel at ntp.org>
* Copyright 2015 by the NTPsec project contributors
* SPDX-License-Identifier: BSD-3-clause
*/
@@ -68,7 +68,7 @@
* feature information
*/
#define PARSEB_S_LEAP 0x00010000 /* supports LEAP */
-#define PARSEB_S_ANTENNA 0x00020000 /* supports antenna information */
+#define PARSEB_S_CALLBIT 0x00020000 /* supports callbit information */
#define PARSEB_S_PPS 0x00040000 /* supports PPS time stamping */
#define PARSEB_S_POSITION 0x00080000 /* supports position information (GPS) */
@@ -94,7 +94,7 @@
#define PARSE_LEAPSECOND(x) (PARSE_SYNC(x) && ((x) & PARSEB_LEAP_SECOND))
#define PARSE_S_LEAP(x) ((x) & PARSEB_S_LEAP)
-#define PARSE_S_ANTENNA(x) ((x) & PARSEB_S_ANTENNA)
+#define PARSE_S_CALLBIT(x) ((x) & PARSEB_S_CALLBIT)
#define PARSE_S_PPS(x) ((x) & PARSEB_S_PPS)
#define PARSE_S_POSITION(x) ((x) & PARSEB_S_POSITION)
diff --git a/libparse/clk_meinberg.c b/libparse/clk_meinberg.c
index f1cf4da..d99da18 100644
--- a/libparse/clk_meinberg.c
+++ b/libparse/clk_meinberg.c
@@ -1,7 +1,7 @@
/*
* Meinberg clock support
*
- * Copyright (c) 1989-2005 by Frank Kardel <kardel at ntp.org>
+ * Copyright (c) 1989-2015 by Frank Kardel <kardel at ntp.org>
* Copyright 2015 by the NTPsec project contributors
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -363,7 +363,7 @@ cvt_meinberg(
if (format->flags & MBG_EXTENDED)
{
- clock_time->flags |= PARSEB_S_ANTENNA;
+ clock_time->flags |= PARSEB_S_CALLBIT;
/*
* DCF77 does not encode the direction -
diff --git a/libparse/clk_rawdcf.c b/libparse/clk_rawdcf.c
index b738243..aaf310f 100644
--- a/libparse/clk_rawdcf.c
+++ b/libparse/clk_rawdcf.c
@@ -1,13 +1,14 @@
/*
* Raw DCF77 pulse clock support
*
- * Copyright (c) 1989-2006 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-2015 by Frank Kardel <kardel <AT> ntp.org>
* Copyright 2015 by the NTPsec project contributors
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#include "ntp_fp.h"
+#include "timevalops.h"
#include "ntp_unixtime.h"
#include "ntp_calendar.h"
@@ -68,7 +69,9 @@ static parse_cvt_fnc_t cvt_rawdcf;
static parse_inp_fnc_t inp_rawdcf;
typedef struct last_tcode {
- time_t tcode; /* last converted time code */
+ time_t tcode; /* last converted time code */
+ timestamp_t tminute; /* sample time for minute start */
+ timestamp_t timeout; /* last timeout timestamp */
} last_tcode_t;
#define BUFFER_MAX 61
@@ -191,7 +194,7 @@ convert_rawdcf(
const unsigned char *c = dcfprm->zerobits;
int i;
- parseprintf(DD_RAWDCF,("parse: convert_rawdcf: \"%s\"\n", buffer));
+ parseprintf(DD_RAWDCF,("parse: convert_rawdcf: \"%.*s\"\n", size, buffer));
if (size < 57)
{
@@ -229,7 +232,7 @@ convert_rawdcf(
*/
parseprintf(DD_RAWDCF,("parse: convert_rawdcf: parity check passed\n"));
- clock_time->flags = PARSEB_S_ANTENNA|PARSEB_S_LEAP;
+ clock_time->flags = PARSEB_S_CALLBIT|PARSEB_S_LEAP;
clock_time->utctime= 0;
clock_time->usecond= 0;
clock_time->second = 0;
@@ -270,7 +273,7 @@ convert_rawdcf(
if (ext_bf(buffer, DCF_R, dcfprm->zerobits))
clock_time->flags |= PARSEB_CALLBIT;
- parseprintf(DD_RAWDCF,("parse: convert_rawdcf: TIME CODE OK: %d:%d, %d.%d.%d, flags 0x%lx\n",
+ parseprintf(DD_RAWDCF,("parse: convert_rawdcf: TIME CODE OK: %02d:%02d, %02d.%02d.%02d, flags 0x%lx\n",
(int)clock_time->hour, (int)clock_time->minute, (int)clock_time->day, (int)clock_time->month,(int) clock_time->year,
(u_long)clock_time->flags));
return CVT_OK;
@@ -280,7 +283,7 @@ convert_rawdcf(
/*
* bad format - not for us
*/
- msyslog(LOG_ERR, "parse: convert_rawdcf: parity check FAILED for \"%s\"", buffer);
+ msyslog(LOG_ERR, "parse: convert_rawdcf: parity check FAILED for \"%.*s\"", size, buffer);
return CVT_FAIL|CVT_BADFMT;
}
}
@@ -442,6 +445,8 @@ cvt_rawdcf(
if (*c) c++;
}
+ *s = '\0';
+
if (rtc == CVT_NONE)
{
rtc = convert_rawdcf(buffer, size, &dcfparameter, clock_time);
@@ -452,14 +457,14 @@ cvt_rawdcf(
newtime = parse_to_unixtime(clock_time, &rtc);
if ((rtc == CVT_OK) && t)
{
- if ((newtime - t->tcode) == 60) /* guard against multi bit errors */
+ if ((newtime - t->tcode) <= 600) /* require a successful telegram within last 10 minutes */
{
- parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: minute delta check OK\n"));
+ parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: recent timestamp check OK\n"));
clock_time->utctime = newtime;
}
else
{
- parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: minute delta check FAIL - ignore timestamp\n"));
+ parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: recent timestamp check FAIL - ignore timestamp\n"));
rtc = CVT_SKIP;
}
t->tcode = newtime;
@@ -493,13 +498,52 @@ pps_rawdcf(
return CVT_NONE;
}
+static long
+calc_usecdiff(
+ timestamp_t *ref,
+ timestamp_t *base,
+ long offset
+ )
+{
+ struct timeval delta;
+ long delta_usec = 0;
+ l_fp delt;
+
+ delt = ref->fp;
+ delt.l_i -= offset;
+ L_SUB(&delt, &base->fp);
+ TSTOTV(&delt, &delta);
+
+ delta_usec = 1000000 * (int32_t)delta.tv_sec + delta.tv_usec;
+ return delta_usec;
+}
+
static u_long
snt_rawdcf(
parse_t *parseio,
timestamp_t *ptime
)
{
- if ((parseio->parse_dtime.parse_status & CVT_MASK) == CVT_OK)
+ /*
+ * only synthesize if all of following conditions are met:
+ * - CVT_OK parse_status (we have a time stamp base)
+ * - ABS(ptime - tminute - (parse_index - 1) sec) < 500ms (spaced by 1 sec +- 500ms)
+ * - minute marker is available (confirms minute raster as base)
+ */
+ last_tcode_t *t = (last_tcode_t *)parseio->parse_pdata;
+ long delta_usec = -1;
+
+ if (t != NULL && t->tminute.tv.tv_sec != 0) {
+ delta_usec = calc_usecdiff(ptime, &t->tminute, parseio->parse_index - 1);
+ if (delta_usec < 0)
+ delta_usec = -delta_usec;
+ }
+
+ parseprintf(DD_RAWDCF,("parse: snt_rawdcf: synth for offset %d seconds - absolute usec error %ld\n",
+ parseio->parse_index - 1, delta_usec));
+
+ if (((parseio->parse_dtime.parse_status & CVT_MASK) == CVT_OK) &&
+ (delta_usec < 500000 && delta_usec >= 0)) /* only if minute marker is available */
{
parseio->parse_dtime.parse_stime = *ptime;
@@ -532,10 +576,43 @@ inp_rawdcf(
if (parse_timedout(parseio, tstamp, &timeout))
{
- parseprintf(DD_PARSE, ("inp_rawdcf: time out seen\n"));
+ last_tcode_t *t = (last_tcode_t *)parseio->parse_pdata;
+ long delta_usec;
+ parseprintf(DD_RAWDCF, ("inp_rawdcf: time out seen\n"));
+ /* finish collection */
(void) parse_end(parseio);
+
+ if (t != NULL)
+ {
+ /* remember minute start sample time if timeouts occur in minute raster */
+ if (t->timeout.tv.tv_sec != 0)
+ {
+ delta_usec = calc_usecdiff(tstamp, &t->timeout, 60);
+ if (delta_usec < 0)
+ delta_usec = -delta_usec;
+ }
+ else
+ {
+ delta_usec = -1;
+ }
+
+ if (delta_usec < 500000 && delta_usec >= 0)
+ {
+ parseprintf(DD_RAWDCF, ("inp_rawdcf: timeout time difference %ld usec - minute marker set\n", delta_usec));
+ /* collect minute markers only if spaced by 60 seconds */
+ t->tminute = *tstamp;
+ }
+ else
+ {
+ parseprintf(DD_RAWDCF, ("inp_rawdcf: timeout time difference %ld usec - minute marker cleared\n", delta_usec));
+ memset((char *)&t->tminute, 0, sizeof(t->tminute));
+ }
+ t->timeout = *tstamp;
+ }
(void) parse_addchar(parseio, ch);
+
+ /* pass up to higher layers */
return PARSE_INP_TIME;
}
else
diff --git a/libparse/clk_schmid.c b/libparse/clk_schmid.c
index 1c590d0..55c31f7 100644
--- a/libparse/clk_schmid.c
+++ b/libparse/clk_schmid.c
@@ -6,7 +6,7 @@
* Schmid clock support
* based on information and testing from Adam W. Feigin et. al (Swisstime iis.ethz.ch)
*
- * Copyright (c) 1989-2005 by Frank Kardel <kardel at ntp.org>
+ * Copyright (c) 1989-2015 by Frank Kardel <kardel at ntp.org>
* Copyright 2015 by the NTPsec project contributors
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -150,7 +150,7 @@ cvt_schmid(
}
}
- clock_time->flags |= PARSEB_S_LEAP|PARSEB_S_ANTENNA;
+ clock_time->flags |= PARSEB_S_LEAP|PARSEB_S_CALLBIT;
return CVT_OK;
}
diff --git a/libparse/parse.c b/libparse/parse.c
index 8610187..b511418 100644
--- a/libparse/parse.c
+++ b/libparse/parse.c
@@ -1,13 +1,7 @@
/*
* Parser module for reference clock
*
- * PARSEKERNEL define switches between two personalities of the module
- * if PARSEKERNEL is defined this module can be used
- * as kernel module. In this case the time stamps will be
- * a struct timeval.
- * when PARSEKERNEL is not defined NTP time stamps will be used.
- *
- * Copyright (c) 1989-2005 by Frank Kardel <kardel at ntp.org>
+ * Copyright (c) 1989-2015 by Frank Kardel <kardel at ntp.org>
* Copyright 2015 by the NTPsec project contributors
* SPDX-License-Identifier: BSD-3-Clause
*
diff --git a/ntpd/refclock_parse.c b/ntpd/refclock_parse.c
index 4d7eb8b..8fbcec1 100644
--- a/ntpd/refclock_parse.c
+++ b/ntpd/refclock_parse.c
@@ -5,7 +5,7 @@
* On systems that support PPSAPI (RFC2783) PPSAPI is the
* preferred interface.
*
- * Copyright (c) 1989-2009 by Frank Kardel <kardel at ntp.org>
+ * Copyright (c) 1989-2015 by Frank Kardel <kardel at ntp.org>
* Copyright 2015 by the NTPsec project contributors
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -2029,7 +2029,7 @@ parsestate(
{
{ PARSEB_S_LEAP, "LEAP INDICATION" },
{ PARSEB_S_PPS, "PPS SIGNAL" },
- { PARSEB_S_ANTENNA, "ANTENNA" },
+ { PARSEB_S_CALLBIT, "CALLBIT" },
{ PARSEB_S_POSITION, "POSITION" },
{ 0, NULL }
};
@@ -2051,7 +2051,7 @@ parsestate(
i++;
}
- if (lstate & (PARSEB_S_LEAP|PARSEB_S_ANTENNA|PARSEB_S_PPS|PARSEB_S_POSITION))
+ if (lstate & (PARSEB_S_LEAP|PARSEB_S_CALLBIT|PARSEB_S_PPS|PARSEB_S_POSITION))
{
if (s != t)
t = ap(buffer, size, t, "; ");
@@ -2482,7 +2482,7 @@ parse_start(
if (!notice)
{
NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
- msyslog(LOG_INFO, "NTP PARSE support: Copyright (c) 1989-2009, Frank Kardel");
+ msyslog(LOG_INFO, "NTP PARSE support: Copyright (c) 1989-2015, Frank Kardel");
notice = 1;
}
More information about the vc
mailing list