|
|
edcb74 |
diff -up ntp-4.2.6p5/config.h.in.tsyncdriver ntp-4.2.6p5/config.h.in
|
|
|
edcb74 |
--- ntp-4.2.6p5/config.h.in.tsyncdriver 2011-12-25 00:32:51.000000000 +0100
|
|
|
edcb74 |
+++ ntp-4.2.6p5/config.h.in 2017-09-19 11:01:08.267218957 +0200
|
|
|
edcb74 |
@@ -159,6 +159,9 @@
|
|
|
edcb74 |
/* Zyfer GPStarplus */
|
|
|
edcb74 |
#undef CLOCK_ZYFER
|
|
|
edcb74 |
|
|
|
edcb74 |
+/* Spectracom TSYNC PCI */
|
|
|
edcb74 |
+#undef CLOCK_TSYNCPCI
|
|
|
edcb74 |
+
|
|
|
edcb74 |
/* Enable ntpd debugging code? */
|
|
|
edcb74 |
#undef DEBUG
|
|
|
edcb74 |
|
|
|
edcb74 |
diff -up ntp-4.2.6p5/configure.tsyncdriver ntp-4.2.6p5/configure
|
|
|
edcb74 |
--- ntp-4.2.6p5/configure.tsyncdriver 2011-12-25 00:31:17.000000000 +0100
|
|
|
edcb74 |
+++ ntp-4.2.6p5/configure 2017-09-19 11:01:08.334221167 +0200
|
|
|
edcb74 |
@@ -22827,6 +22827,7 @@ esac
|
|
|
edcb74 |
$as_echo "$ans" >&6; }
|
|
|
edcb74 |
|
|
|
edcb74 |
|
|
|
edcb74 |
+$as_echo "#define CLOCK_TSYNCPCI 1" >>confdefs.h
|
|
|
edcb74 |
|
|
|
edcb74 |
|
|
|
edcb74 |
|
|
|
edcb74 |
diff -up ntp-4.2.6p5/html/drivers/driver45.html.tsyncdriver ntp-4.2.6p5/html/drivers/driver45.html
|
|
|
edcb74 |
--- ntp-4.2.6p5/html/drivers/driver45.html.tsyncdriver 2017-09-19 11:01:08.269219023 +0200
|
|
|
edcb74 |
+++ ntp-4.2.6p5/html/drivers/driver45.html 2017-09-19 11:01:08.269219023 +0200
|
|
|
edcb74 |
@@ -0,0 +1,32 @@
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+<html>
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ <head>
|
|
|
edcb74 |
+ <meta http-equiv="content-type" content="text/html;charset=iso-8859-1">
|
|
|
edcb74 |
+ <title>Spectracom TSYNC PCI</title>
|
|
|
edcb74 |
+ <link href="scripts/style.css" type="text/css" rel="stylesheet">
|
|
|
edcb74 |
+ </head>
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ <body>
|
|
|
edcb74 |
+ Spectracom TSYNC PCI
|
|
|
edcb74 |
+Last update:
|
|
|
edcb74 |
+ 26-Mar-2012 05:10
|
|
|
edcb74 |
+ UTC
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ Synopsis
|
|
|
edcb74 |
+ Address: 127.127.45.u
|
|
|
edcb74 |
+ Reference ID: one of <tt>GPS</tt>, <tt>IRIG</tt>, <tt>HVQ</tt>, <tt>FREQ</tt>, <tt>ACTS</tt>, <tt>PPS</tt>, <tt>PTP</tt>, <tt>ACT</tt>, <tt>USR</tt>, <tt>LOCL</tt>
|
|
|
edcb74 |
+ Driver ID: <tt>Spectracom TSYNC PCI</tt>
|
|
|
edcb74 |
+ Driver Port: <tt>/dev/tsyncpciu</tt>
|
|
|
edcb74 |
+ Features: <tt>(none)</tt>
|
|
|
edcb74 |
+ Description
|
|
|
edcb74 |
+ This driver supports the
|
|
|
edcb74 |
+ href="http://www.spectracomcorp.com/ProductsServices/TimingSynchronization/BuslevelTiming">Spectracom TSYNC PCI receiver.
|
|
|
edcb74 |
+ Additional Information
|
|
|
edcb74 |
+ Reference Clock Drivers
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ <script type="text/javascript" language="javascript" src="scripts/footer.txt"></script>
|
|
|
edcb74 |
+ </body>
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+</html>
|
|
|
edcb74 |
diff -up ntp-4.2.6p5/html/refclock.html.tsyncdriver ntp-4.2.6p5/html/refclock.html
|
|
|
edcb74 |
--- ntp-4.2.6p5/html/refclock.html.tsyncdriver 2009-12-09 08:36:36.000000000 +0100
|
|
|
edcb74 |
+++ ntp-4.2.6p5/html/refclock.html 2017-09-19 11:01:08.269219023 +0200
|
|
|
edcb74 |
@@ -82,9 +82,10 @@
|
|
|
edcb74 |
Type 42 Zyfer GPStarplus Receiver
|
|
|
edcb74 |
Type 43 RIPE NCC interface for Trimble Palisade
|
|
|
edcb74 |
Type 44 NeoClock4X - DCF77 / TDF serial line
|
|
|
edcb74 |
+ Type 45 Spectracom TSYNC PCI
|
|
|
edcb74 |
|
|
|
edcb74 |
|
|
|
edcb74 |
<script type="text/javascript" language="javascript" src="scripts/footer.txt"></script>
|
|
|
edcb74 |
</body>
|
|
|
edcb74 |
|
|
|
edcb74 |
-</html>
|
|
|
edcb74 |
\ No newline at end of file
|
|
|
edcb74 |
+</html>
|
|
|
edcb74 |
diff -up ntp-4.2.6p5/include/ntp.h.tsyncdriver ntp-4.2.6p5/include/ntp.h
|
|
|
edcb74 |
--- ntp-4.2.6p5/include/ntp.h.tsyncdriver 2017-09-19 11:01:08.246218264 +0200
|
|
|
edcb74 |
+++ ntp-4.2.6p5/include/ntp.h 2017-09-19 11:01:08.269219023 +0200
|
|
|
edcb74 |
@@ -525,7 +525,8 @@ struct peer {
|
|
|
edcb74 |
#define REFCLK_ZYFER 42 /* Zyfer GPStarplus receiver */
|
|
|
edcb74 |
#define REFCLK_RIPENCC 43 /* RIPE NCC Trimble driver */
|
|
|
edcb74 |
#define REFCLK_NEOCLOCK4X 44 /* NeoClock4X DCF77 or TDF receiver */
|
|
|
edcb74 |
-#define REFCLK_MAX 44 /* NeoClock4X DCF77 or TDF receiver */
|
|
|
edcb74 |
+#define REFCLK_TSYNCPCI 45 /* Spectracom TSYNC PCI timing board */
|
|
|
edcb74 |
+#define REFCLK_MAX 45 /* Spectracom TSYNC PCI timing board */
|
|
|
edcb74 |
|
|
|
edcb74 |
|
|
|
edcb74 |
/*
|
|
|
edcb74 |
diff -up ntp-4.2.6p5/libntp/clocktypes.c.tsyncdriver ntp-4.2.6p5/libntp/clocktypes.c
|
|
|
edcb74 |
--- ntp-4.2.6p5/libntp/clocktypes.c.tsyncdriver 2009-12-09 08:36:37.000000000 +0100
|
|
|
edcb74 |
+++ ntp-4.2.6p5/libntp/clocktypes.c 2017-09-19 11:01:08.270219055 +0200
|
|
|
edcb74 |
@@ -100,6 +100,8 @@ struct clktype clktypes[] = {
|
|
|
edcb74 |
"GPS_RIPENCC" },
|
|
|
edcb74 |
{ REFCLK_NEOCLOCK4X, "NeoClock4X DCF77 / TDF receiver (44)",
|
|
|
edcb74 |
"NEOCLK4X"},
|
|
|
edcb74 |
+ { REFCLK_TSYNCPCI, "Spectracom TSYNC PCI timing board (45)",
|
|
|
edcb74 |
+ "PCI_TSYNC"},
|
|
|
edcb74 |
{ -1, "", "" }
|
|
|
edcb74 |
};
|
|
|
edcb74 |
|
|
|
edcb74 |
diff -up ntp-4.2.6p5/ntpd/Makefile.in.tsyncdriver ntp-4.2.6p5/ntpd/Makefile.in
|
|
|
edcb74 |
--- ntp-4.2.6p5/ntpd/Makefile.in.tsyncdriver 2011-12-25 00:31:11.000000000 +0100
|
|
|
edcb74 |
+++ ntp-4.2.6p5/ntpd/Makefile.in 2017-09-19 11:01:08.270219055 +0200
|
|
|
edcb74 |
@@ -97,6 +97,7 @@ am_libntpd_a_OBJECTS = ntp_control.$(OBJ
|
|
|
edcb74 |
refclock_tpro.$(OBJEXT) refclock_true.$(OBJEXT) \
|
|
|
edcb74 |
refclock_tt560.$(OBJEXT) refclock_ulink.$(OBJEXT) \
|
|
|
edcb74 |
refclock_wwv.$(OBJEXT) refclock_wwvb.$(OBJEXT) \
|
|
|
edcb74 |
+ refclock_tsyncpci.$(OBJEXT) \
|
|
|
edcb74 |
refclock_zyfer.$(OBJEXT) $(am__objects_1)
|
|
|
edcb74 |
libntpd_a_OBJECTS = $(am_libntpd_a_OBJECTS)
|
|
|
edcb74 |
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" \
|
|
|
edcb74 |
@@ -499,6 +500,7 @@ libntpd_a_SOURCES = \
|
|
|
edcb74 |
refclock_wwv.c \
|
|
|
edcb74 |
refclock_wwvb.c \
|
|
|
edcb74 |
refclock_zyfer.c \
|
|
|
edcb74 |
+ refclock_tsyncpci.c \
|
|
|
edcb74 |
$(NULL)
|
|
|
edcb74 |
|
|
|
edcb74 |
all: $(BUILT_SOURCES)
|
|
|
edcb74 |
@@ -734,6 +736,7 @@ distclean-compile:
|
|
|
edcb74 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refclock_wwv.Po@am__quote@
|
|
|
edcb74 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refclock_wwvb.Po@am__quote@
|
|
|
edcb74 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refclock_zyfer.Po@am__quote@
|
|
|
edcb74 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refclock_tsyncpci.Po@am__quote@
|
|
|
edcb74 |
|
|
|
edcb74 |
.c.o:
|
|
|
edcb74 |
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
|
|
edcb74 |
diff -up ntp-4.2.6p5/ntpd/ntp_control.c.tsyncdriver ntp-4.2.6p5/ntpd/ntp_control.c
|
|
|
edcb74 |
--- ntp-4.2.6p5/ntpd/ntp_control.c.tsyncdriver 2017-09-19 11:01:08.266218923 +0200
|
|
|
edcb74 |
+++ ntp-4.2.6p5/ntpd/ntp_control.c 2017-09-19 11:01:08.270219055 +0200
|
|
|
edcb74 |
@@ -419,6 +419,7 @@ static u_char clocktypes[] = {
|
|
|
edcb74 |
CTL_SST_TS_UHF, /* REFCLK_ZYFER (42) */
|
|
|
edcb74 |
CTL_SST_TS_UHF, /* REFCLK_RIPENCC (43) */
|
|
|
edcb74 |
CTL_SST_TS_UHF, /* REFCLK_NEOCLOCK4X (44) */
|
|
|
edcb74 |
+ CTL_SST_TS_UHF, /* REFCLK_TSYNCPCI (45) */
|
|
|
edcb74 |
};
|
|
|
edcb74 |
|
|
|
edcb74 |
|
|
|
edcb74 |
diff -up ntp-4.2.6p5/ntpd/refclock_conf.c.tsyncdriver ntp-4.2.6p5/ntpd/refclock_conf.c
|
|
|
edcb74 |
--- ntp-4.2.6p5/ntpd/refclock_conf.c.tsyncdriver 2011-01-04 02:57:27.000000000 +0100
|
|
|
edcb74 |
+++ ntp-4.2.6p5/ntpd/refclock_conf.c 2017-09-19 11:01:08.270219055 +0200
|
|
|
edcb74 |
@@ -258,6 +258,12 @@ extern struct refclock refclock_neoclock
|
|
|
edcb74 |
#define refclock_neoclock4x refclock_none
|
|
|
edcb74 |
#endif
|
|
|
edcb74 |
|
|
|
edcb74 |
+#ifdef CLOCK_TSYNCPCI
|
|
|
edcb74 |
+extern struct refclock refclock_tsyncpci;
|
|
|
edcb74 |
+#else
|
|
|
edcb74 |
+#define refclock_tsyncpci refclock_none
|
|
|
edcb74 |
+#endif
|
|
|
edcb74 |
+
|
|
|
edcb74 |
/*
|
|
|
edcb74 |
* Order is clock_start(), clock_shutdown(), clock_poll(),
|
|
|
edcb74 |
* clock_control(), clock_init(), clock_buginfo, clock_flags;
|
|
|
edcb74 |
@@ -309,7 +315,8 @@ struct refclock * const refclock_conf[]
|
|
|
edcb74 |
&refclock_tt560, /* 41 REFCLK_TT560 */
|
|
|
edcb74 |
&refclock_zyfer, /* 42 REFCLK_ZYFER */
|
|
|
edcb74 |
&refclock_ripencc, /* 43 REFCLK_RIPENCC */
|
|
|
edcb74 |
- &refclock_neoclock4x /* 44 REFCLK_NEOCLOCK4X */
|
|
|
edcb74 |
+ &refclock_neoclock4x, /* 44 REFCLK_NEOCLOCK4X */
|
|
|
edcb74 |
+ &refclock_tsyncpci /* 45 REFCLK_TSYNCPCI */
|
|
|
edcb74 |
};
|
|
|
edcb74 |
|
|
|
edcb74 |
u_char num_refclock_conf = sizeof(refclock_conf)/sizeof(struct refclock *);
|
|
|
edcb74 |
diff -up ntp-4.2.6p5/ntpd/refclock_tsyncpci.c.tsyncdriver ntp-4.2.6p5/ntpd/refclock_tsyncpci.c
|
|
|
edcb74 |
--- ntp-4.2.6p5/ntpd/refclock_tsyncpci.c.tsyncdriver 2017-09-19 11:01:08.271219088 +0200
|
|
|
edcb74 |
+++ ntp-4.2.6p5/ntpd/refclock_tsyncpci.c 2017-09-19 11:04:55.261709585 +0200
|
|
|
edcb74 |
@@ -0,0 +1,922 @@
|
|
|
edcb74 |
+/*******************************************************************************
|
|
|
edcb74 |
+*
|
|
|
edcb74 |
+* Module : refclock_tsyncpci.c
|
|
|
edcb74 |
+* Date : 09/08/08
|
|
|
edcb74 |
+* Purpose : Implements a reference clock driver for the NTP daemon. This
|
|
|
edcb74 |
+* reference clock driver provides a means to communicate with
|
|
|
edcb74 |
+* the Spectracom TSYNC PCI timing devices and use them as a time
|
|
|
edcb74 |
+* source.
|
|
|
edcb74 |
+*
|
|
|
edcb74 |
+* (C) Copyright 2008 Spectracom Corporation
|
|
|
edcb74 |
+*
|
|
|
edcb74 |
+* This software is provided by Spectracom Corporation 'as is' and
|
|
|
edcb74 |
+* any express or implied warranties, including, but not limited to, the
|
|
|
edcb74 |
+* implied warranties of merchantability and fitness for a particular purpose
|
|
|
edcb74 |
+* are disclaimed. In no event shall Spectracom Corporation be liable
|
|
|
edcb74 |
+* for any direct, indirect, incidental, special, exemplary, or consequential
|
|
|
edcb74 |
+* damages (including, but not limited to, procurement of substitute goods
|
|
|
edcb74 |
+* or services; loss of use, data, or profits; or business interruption)
|
|
|
edcb74 |
+* however caused and on any theory of liability, whether in contract, strict
|
|
|
edcb74 |
+* liability, or tort (including negligence or otherwise) arising in any way
|
|
|
edcb74 |
+* out of the use of this software, even if advised of the possibility of
|
|
|
edcb74 |
+* such damage.
|
|
|
edcb74 |
+*
|
|
|
edcb74 |
+* This software is released for distribution according to the NTP copyright
|
|
|
edcb74 |
+* and license contained in html/copyright.html of NTP source.
|
|
|
edcb74 |
+*
|
|
|
edcb74 |
+*******************************************************************************/
|
|
|
edcb74 |
+#ifdef HAVE_CONFIG_H
|
|
|
edcb74 |
+#include <config.h>
|
|
|
edcb74 |
+#endif
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+#if defined(REFCLOCK) && defined(CLOCK_TSYNCPCI)
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+#include <asm/ioctl.h>
|
|
|
edcb74 |
+#ifdef HAVE_SYS_IOCTL_H
|
|
|
edcb74 |
+# include <sys/ioctl.h>
|
|
|
edcb74 |
+#endif
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+#include <stdio.h>
|
|
|
edcb74 |
+#include <ctype.h>
|
|
|
edcb74 |
+#include <netinet/in.h>
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+#include "ntpd.h"
|
|
|
edcb74 |
+#include "ntp_io.h"
|
|
|
edcb74 |
+#include "ntp_refclock.h"
|
|
|
edcb74 |
+#include "ntp_unixtime.h"
|
|
|
edcb74 |
+#include "ntp_stdlib.h"
|
|
|
edcb74 |
+#include "ntp_calendar.h"
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*******************************************************************************
|
|
|
edcb74 |
+**
|
|
|
edcb74 |
+** This driver supports the Spectracom TSYNC PCI GPS receiver. It requires
|
|
|
edcb74 |
+** that the tsyncpci.o device driver be installed and loaded.
|
|
|
edcb74 |
+**
|
|
|
edcb74 |
+*******************************************************************************/
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+#define TSYNC_PCI_REVISION "1.11"
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** TPRO interface definitions
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+#define DEVICE "/dev/tsyncpci" /* device name */
|
|
|
edcb74 |
+#define PRECISION (-20) /* precision assumed (1 us) */
|
|
|
edcb74 |
+#define DESCRIPTION "Spectracom TSYNC-PCI" /* WRU */
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+#define SECONDS_1900_TO_1970 (2208988800U)
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+#define TSYNC_REF_IID (0x2500) // SS CAI, REF IID
|
|
|
edcb74 |
+#define TSYNC_REF_DEST_ID (0x0001) // KTS Firmware
|
|
|
edcb74 |
+#define TSYNC_REF_IN_PYLD_OFF (0)
|
|
|
edcb74 |
+#define TSYNC_REF_IN_LEN (0)
|
|
|
edcb74 |
+#define TSYNC_REF_OUT_PYLD_OFF (0)
|
|
|
edcb74 |
+#define TSYNC_REF_OUT_LEN (8)
|
|
|
edcb74 |
+#define TSYNC_REF_MAX_OUT_LEN (16)
|
|
|
edcb74 |
+#define TSYNC_REF_PYLD_LEN (TSYNC_REF_IN_LEN + \
|
|
|
edcb74 |
+ TSYNC_REF_MAX_OUT_LEN)
|
|
|
edcb74 |
+#define TSYNC_REF_LEN (4)
|
|
|
edcb74 |
+#define TSYNC_REF_LOCAL ("LOCL")
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+#define TSYNC_TMSCL_IID (0x2301) // CS CAI, TIMESCALE IID
|
|
|
edcb74 |
+#define TSYNC_TMSCL_DEST_ID (0x0001) // KTS Firmware
|
|
|
edcb74 |
+#define TSYNC_TMSCL_IN_PYLD_OFF (0)
|
|
|
edcb74 |
+#define TSYNC_TMSCL_IN_LEN (0)
|
|
|
edcb74 |
+#define TSYNC_TMSCL_OUT_PYLD_OFF (0)
|
|
|
edcb74 |
+#define TSYNC_TMSCL_OUT_LEN (4)
|
|
|
edcb74 |
+#define TSYNC_TMSCL_MAX_OUT_LEN (12)
|
|
|
edcb74 |
+#define TSYNC_TMSCL_PYLD_LEN (TSYNC_TMSCL_IN_LEN + \
|
|
|
edcb74 |
+ TSYNC_TMSCL_MAX_OUT_LEN)
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+#define TSYNC_LEAP_IID (0x2307) // CS CAI, LEAP SEC IID
|
|
|
edcb74 |
+#define TSYNC_LEAP_DEST_ID (0x0001) // KTS Firmware
|
|
|
edcb74 |
+#define TSYNC_LEAP_IN_PYLD_OFF (0)
|
|
|
edcb74 |
+#define TSYNC_LEAP_IN_LEN (0)
|
|
|
edcb74 |
+#define TSYNC_LEAP_OUT_PYLD_OFF (0)
|
|
|
edcb74 |
+#define TSYNC_LEAP_OUT_LEN (28)
|
|
|
edcb74 |
+#define TSYNC_LEAP_MAX_OUT_LEN (36)
|
|
|
edcb74 |
+#define TSYNC_LEAP_PYLD_LEN (TSYNC_LEAP_IN_LEN + \
|
|
|
edcb74 |
+ TSYNC_LEAP_MAX_OUT_LEN)
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+// These define the base date/time of the system clock. The system time will
|
|
|
edcb74 |
+// be tracked as the number of seconds from this date/time.
|
|
|
edcb74 |
+#define TSYNC_TIME_BASE_YEAR (1970) // earliest acceptable year
|
|
|
edcb74 |
+#define TSYNC_SECS_PER_MIN (60)
|
|
|
edcb74 |
+#define TSYNC_MINS_PER_HR (60)
|
|
|
edcb74 |
+#define TSYNC_HRS_PER_DAY (24)
|
|
|
edcb74 |
+#define TSYNC_DAYS_PER_YR (365)
|
|
|
edcb74 |
+#define TSYNC_DAYS_PER_LYR (366)
|
|
|
edcb74 |
+#define TSYNC_SECS_PER_HR (TSYNC_MINS_PER_HR * TSYNC_SECS_PER_MIN)
|
|
|
edcb74 |
+#define TSYNC_SECS_PER_DAY (TSYNC_HRS_PER_DAY * TSYNC_SECS_PER_HR)
|
|
|
edcb74 |
+#define TSYNC_SECS_PER_YR (TSYNC_DAYS_PER_YR * TSYNC_SECS_PER_DAY)
|
|
|
edcb74 |
+#define TSYNC_SECS_PER_LYR (TSYNC_DAYS_PER_LYR * TSYNC_SECS_PER_DAY)
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+#define TSYNC_LCL_STRATUM (0)
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** TSYNC Time Scales type
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+typedef enum
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+ TIME_SCALE_UTC = 0, // Universal Coordinated Time
|
|
|
edcb74 |
+ TIME_SCALE_TAI = 1, // International Atomic Time
|
|
|
edcb74 |
+ TIME_SCALE_GPS = 2, // Global Positioning System
|
|
|
edcb74 |
+ TIME_SCALE_LOCAL = 3, // UTC w/local rules for time zone and DST
|
|
|
edcb74 |
+ NUM_TIME_SCALES = 4, // Number of time scales
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ TIME_SCALE_MAX = 15 // Maximum number of timescales
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} TIME_SCALE;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** TSYNC Board Object
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+typedef struct BoardObj {
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ int file_descriptor;
|
|
|
edcb74 |
+ unsigned short devid;
|
|
|
edcb74 |
+ unsigned short options;
|
|
|
edcb74 |
+ unsigned char firmware[5];
|
|
|
edcb74 |
+ unsigned char FPGA[5];
|
|
|
edcb74 |
+ unsigned char driver[7];
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} BoardObj;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** TSYNC Time Object
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+typedef struct TimeObj {
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ unsigned char syncOption; /* -M option */
|
|
|
edcb74 |
+ unsigned int secsDouble; /* seconds floating pt */
|
|
|
edcb74 |
+ unsigned char seconds; /* seconds whole num */
|
|
|
edcb74 |
+ unsigned char minutes;
|
|
|
edcb74 |
+ unsigned char hours;
|
|
|
edcb74 |
+ unsigned short days;
|
|
|
edcb74 |
+ unsigned short year;
|
|
|
edcb74 |
+ unsigned short flags; /* bit 2 SYNC, bit 1 TCODE; all others 0 */
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} TimeObj;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** NTP Time Object
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+typedef struct NtpTimeObj {
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ TimeObj timeObj;
|
|
|
edcb74 |
+ struct timeval tv;
|
|
|
edcb74 |
+ unsigned int refId;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} NtpTimeObj;
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** TSYNC Supervisor Reference Object
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+typedef struct ReferenceObj {
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ char time[TSYNC_REF_LEN];
|
|
|
edcb74 |
+ char pps[TSYNC_REF_LEN];
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} ReferenceObj;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** TSYNC Seconds Time Object
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+typedef struct SecTimeObj
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+ unsigned int seconds;
|
|
|
edcb74 |
+ unsigned int ns;
|
|
|
edcb74 |
+}
|
|
|
edcb74 |
+SecTimeObj;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** TSYNC DOY Time Object
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+typedef struct DoyTimeObj
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+ unsigned int year;
|
|
|
edcb74 |
+ unsigned int doy;
|
|
|
edcb74 |
+ unsigned int hour;
|
|
|
edcb74 |
+ unsigned int minute;
|
|
|
edcb74 |
+ unsigned int second;
|
|
|
edcb74 |
+ unsigned int ns;
|
|
|
edcb74 |
+}
|
|
|
edcb74 |
+DoyTimeObj;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** TSYNC Leap Second Object
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+typedef struct LeapSecondObj
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+ int offset;
|
|
|
edcb74 |
+ DoyTimeObj utcDate;
|
|
|
edcb74 |
+}
|
|
|
edcb74 |
+LeapSecondObj;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+ * structures for ioctl interactions with driver
|
|
|
edcb74 |
+ */
|
|
|
edcb74 |
+#define DI_PAYLOADS_STARTER_LENGTH 4
|
|
|
edcb74 |
+typedef struct ioctl_trans_di {
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // input parameters
|
|
|
edcb74 |
+ uint16_t dest;
|
|
|
edcb74 |
+ uint16_t iid;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ uint32_t inPayloadOffset;
|
|
|
edcb74 |
+ uint32_t inLength;
|
|
|
edcb74 |
+ uint32_t outPayloadOffset;
|
|
|
edcb74 |
+ uint32_t maxOutLength;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // output parameters
|
|
|
edcb74 |
+ uint32_t actualOutLength;
|
|
|
edcb74 |
+ int32_t status;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Input and output
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // The payloads field MUST be last in ioctl_trans_di.
|
|
|
edcb74 |
+ uint8_t payloads[DI_PAYLOADS_STARTER_LENGTH];
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+}ioctl_trans_di;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+ * structure for looking up a reference ID from a reference name
|
|
|
edcb74 |
+ */
|
|
|
edcb74 |
+typedef struct
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+ const char* pRef; // KTS Reference Name
|
|
|
edcb74 |
+ const char* pRefId; // NTP Reference ID
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} RefIdLookup;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+ * unit control structure
|
|
|
edcb74 |
+ */
|
|
|
edcb74 |
+typedef struct {
|
|
|
edcb74 |
+ uint32_t refPrefer; // Reference prefer flag
|
|
|
edcb74 |
+ uint32_t refId; // Host peer reference ID
|
|
|
edcb74 |
+ uint8_t refStratum; // Host peer reference stratum
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} TsyncUnit;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** Function prototypes
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+static void tsync_poll (int unit, struct peer *);
|
|
|
edcb74 |
+static void tsync_shutdown (int, struct peer *);
|
|
|
edcb74 |
+static int tsync_start (int, struct peer *);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** Helper functions
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+static void ApplyTimeOffset (DoyTimeObj* pDt, int off);
|
|
|
edcb74 |
+static void SecTimeFromDoyTime (SecTimeObj* pSt, DoyTimeObj* pDt);
|
|
|
edcb74 |
+static void DoyTimeFromSecTime (DoyTimeObj* pDt, SecTimeObj* pSt);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+** Transfer vector
|
|
|
edcb74 |
+*/
|
|
|
edcb74 |
+struct refclock refclock_tsyncpci = {
|
|
|
edcb74 |
+ tsync_start, /* start up driver */
|
|
|
edcb74 |
+ tsync_shutdown, /* shut down driver */
|
|
|
edcb74 |
+ tsync_poll, /* transmit poll message */
|
|
|
edcb74 |
+ noentry, /* not used (old tsync_control) */
|
|
|
edcb74 |
+ noentry, /* initialize driver (not used) */
|
|
|
edcb74 |
+ noentry, /* not used (old tsync_buginfo) */
|
|
|
edcb74 |
+ NOFLAGS /* not used */
|
|
|
edcb74 |
+};
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*
|
|
|
edcb74 |
+ * Reference ID lookup table
|
|
|
edcb74 |
+ */
|
|
|
edcb74 |
+static RefIdLookup RefIdLookupTbl[] =
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+ {"gps", "GPS"},
|
|
|
edcb74 |
+ {"ir", "IRIG"},
|
|
|
edcb74 |
+ {"hvq", "HVQ"},
|
|
|
edcb74 |
+ {"frq", "FREQ"},
|
|
|
edcb74 |
+ {"mdm", "ACTS"},
|
|
|
edcb74 |
+ {"epp", "PPS"},
|
|
|
edcb74 |
+ {"ptp", "PTP"},
|
|
|
edcb74 |
+ {"asc", "ATC"},
|
|
|
edcb74 |
+ {"hst0", "USER"},
|
|
|
edcb74 |
+ {"hst", TSYNC_REF_LOCAL},
|
|
|
edcb74 |
+ {"self", TSYNC_REF_LOCAL},
|
|
|
edcb74 |
+ {NULL, NULL}
|
|
|
edcb74 |
+};
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*******************************************************************************
|
|
|
edcb74 |
+** IOCTL DEFINITIONS
|
|
|
edcb74 |
+*******************************************************************************/
|
|
|
edcb74 |
+#define IOCTL_TPRO_ID 't'
|
|
|
edcb74 |
+#define IOCTL_TPRO_OPEN _IOWR(IOCTL_TPRO_ID, 0, BoardObj)
|
|
|
edcb74 |
+#define IOCTL_TPRO_GET_NTP_TIME _IOWR(IOCTL_TPRO_ID, 25, NtpTimeObj)
|
|
|
edcb74 |
+#define IOCTL_TSYNC_GET _IOWR(IOCTL_TPRO_ID, 26, ioctl_trans_di)
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/******************************************************************************
|
|
|
edcb74 |
+ *
|
|
|
edcb74 |
+ * Function: tsync_start()
|
|
|
edcb74 |
+ * Description: Used to intialize the Spectracom TSYNC reference driver.
|
|
|
edcb74 |
+ *
|
|
|
edcb74 |
+ * Parameters:
|
|
|
edcb74 |
+ * IN: unit - not used.
|
|
|
edcb74 |
+ * *peer - pointer to this reference clock's peer structure
|
|
|
edcb74 |
+ * Returns: 0 - unsuccessful
|
|
|
edcb74 |
+ * 1 - successful
|
|
|
edcb74 |
+ *
|
|
|
edcb74 |
+*******************************************************************************/
|
|
|
edcb74 |
+static int tsync_start(int unit, struct peer *peer)
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+ struct refclockproc *pp;
|
|
|
edcb74 |
+ TsyncUnit *up;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /*
|
|
|
edcb74 |
+ ** initialize reference clock and peer parameters
|
|
|
edcb74 |
+ */
|
|
|
edcb74 |
+ pp = peer->procptr;
|
|
|
edcb74 |
+ pp->clockdesc = DESCRIPTION;
|
|
|
edcb74 |
+ pp->io.clock_recv = noentry;
|
|
|
edcb74 |
+ pp->io.srcclock = (caddr_t)peer;
|
|
|
edcb74 |
+ pp->io.datalen = 0;
|
|
|
edcb74 |
+ peer->precision = PRECISION;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Allocate and initialize unit structure
|
|
|
edcb74 |
+ if (!(up = (TsyncUnit*)emalloc(sizeof(TsyncUnit))))
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ return (0);
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Store reference preference
|
|
|
edcb74 |
+ up->refPrefer = peer->flags & FLAG_PREFER;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Initialize reference stratum level and ID
|
|
|
edcb74 |
+ up->refStratum = STRATUM_UNSPEC;
|
|
|
edcb74 |
+ strncpy((char *)&up->refId, TSYNC_REF_LOCAL, TSYNC_REF_LEN);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Attach unit structure
|
|
|
edcb74 |
+ pp->unitptr = (caddr_t)up;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Declare our refId as local in the beginning because we do not know
|
|
|
edcb74 |
+ * what our actual refid is yet.
|
|
|
edcb74 |
+ */
|
|
|
edcb74 |
+ strncpy((char *)&pp->refid, TSYNC_REF_LOCAL, TSYNC_REF_LEN);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ return (1);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} /* End - tsync_start() */
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/*******************************************************************************
|
|
|
edcb74 |
+**
|
|
|
edcb74 |
+** Function: tsync_shutdown()
|
|
|
edcb74 |
+** Description: Handles anything related to shutting down the reference clock
|
|
|
edcb74 |
+** driver. Nothing at this point in time.
|
|
|
edcb74 |
+**
|
|
|
edcb74 |
+** Parameters:
|
|
|
edcb74 |
+** IN: unit - not used.
|
|
|
edcb74 |
+** *peer - pointer to this reference clock's peer structure
|
|
|
edcb74 |
+** Returns: none.
|
|
|
edcb74 |
+**
|
|
|
edcb74 |
+*******************************************************************************/
|
|
|
edcb74 |
+static void tsync_shutdown(int unit, struct peer *peer)
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} /* End - tsync_shutdown() */
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+/******************************************************************************
|
|
|
edcb74 |
+ *
|
|
|
edcb74 |
+ * Function: tsync_poll()
|
|
|
edcb74 |
+ * Description: Retrieve time from the TSYNC device.
|
|
|
edcb74 |
+ *
|
|
|
edcb74 |
+ * Parameters:
|
|
|
edcb74 |
+ * IN: unit - not used.
|
|
|
edcb74 |
+ * *peer - pointer to this reference clock's peer structure
|
|
|
edcb74 |
+ * Returns: none.
|
|
|
edcb74 |
+ *
|
|
|
edcb74 |
+*******************************************************************************/
|
|
|
edcb74 |
+static void tsync_poll(int unit, struct peer *peer)
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+ char device[32];
|
|
|
edcb74 |
+ struct refclockproc *pp;
|
|
|
edcb74 |
+ struct calendar jt;
|
|
|
edcb74 |
+ TsyncUnit *up;
|
|
|
edcb74 |
+ unsigned char synch;
|
|
|
edcb74 |
+ double seconds;
|
|
|
edcb74 |
+ int err;
|
|
|
edcb74 |
+ int err1;
|
|
|
edcb74 |
+ int err2;
|
|
|
edcb74 |
+ int err3;
|
|
|
edcb74 |
+ int i;
|
|
|
edcb74 |
+ int j;
|
|
|
edcb74 |
+ unsigned int itAllocationLength;
|
|
|
edcb74 |
+ unsigned int itAllocationLength1;
|
|
|
edcb74 |
+ unsigned int itAllocationLength2;
|
|
|
edcb74 |
+ NtpTimeObj TimeContext;
|
|
|
edcb74 |
+ BoardObj hBoard;
|
|
|
edcb74 |
+ char timeRef[TSYNC_REF_LEN + 1];
|
|
|
edcb74 |
+ char ppsRef [TSYNC_REF_LEN + 1];
|
|
|
edcb74 |
+ TIME_SCALE tmscl = TIME_SCALE_UTC;
|
|
|
edcb74 |
+ LeapSecondObj leapSec;
|
|
|
edcb74 |
+ ioctl_trans_di *it;
|
|
|
edcb74 |
+ ioctl_trans_di *it1;
|
|
|
edcb74 |
+ ioctl_trans_di *it2;
|
|
|
edcb74 |
+ l_fp offset;
|
|
|
edcb74 |
+ l_fp ltemp;
|
|
|
edcb74 |
+ ReferenceObj * pRefObj;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Construct the device name */
|
|
|
edcb74 |
+ sprintf(device, "%s%d", DEVICE, (int)peer->refclkunit);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ printf("Polling device number %d...\n", (int)peer->refclkunit);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Open the TSYNC device */
|
|
|
edcb74 |
+ hBoard.file_descriptor = open(device, O_RDONLY | O_NDELAY, 0777);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* If error opening TSYNC device... */
|
|
|
edcb74 |
+ if (hBoard.file_descriptor < 0)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ msyslog(LOG_ERR, "Couldn't open device");
|
|
|
edcb74 |
+ return;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* If error while initializing the board... */
|
|
|
edcb74 |
+ if (ioctl(hBoard.file_descriptor, IOCTL_TPRO_OPEN, &hBoard) < 0)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ msyslog(LOG_ERR, "Couldn't initialize device");
|
|
|
edcb74 |
+ close(hBoard.file_descriptor);
|
|
|
edcb74 |
+ return;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Allocate memory for ioctl message */
|
|
|
edcb74 |
+ itAllocationLength =
|
|
|
edcb74 |
+ (sizeof(ioctl_trans_di) - DI_PAYLOADS_STARTER_LENGTH) +
|
|
|
edcb74 |
+ TSYNC_REF_IN_LEN + TSYNC_REF_MAX_OUT_LEN;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ it = (ioctl_trans_di*)alloca(itAllocationLength);
|
|
|
edcb74 |
+ if (it == NULL) {
|
|
|
edcb74 |
+ msyslog(LOG_ERR, "Couldn't allocate transaction memory - Reference");
|
|
|
edcb74 |
+ return;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Build SS_GetRef ioctl message */
|
|
|
edcb74 |
+ it->dest = TSYNC_REF_DEST_ID;
|
|
|
edcb74 |
+ it->iid = TSYNC_REF_IID;
|
|
|
edcb74 |
+ it->inPayloadOffset = TSYNC_REF_IN_PYLD_OFF;
|
|
|
edcb74 |
+ it->inLength = TSYNC_REF_IN_LEN;
|
|
|
edcb74 |
+ it->outPayloadOffset = TSYNC_REF_OUT_PYLD_OFF;
|
|
|
edcb74 |
+ it->maxOutLength = TSYNC_REF_MAX_OUT_LEN;
|
|
|
edcb74 |
+ it->actualOutLength = 0;
|
|
|
edcb74 |
+ it->status = 0;
|
|
|
edcb74 |
+ memset(it->payloads, 0, TSYNC_REF_MAX_OUT_LEN);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Read the reference from the TSYNC-PCI device */
|
|
|
edcb74 |
+ err = ioctl(hBoard.file_descriptor,
|
|
|
edcb74 |
+ IOCTL_TSYNC_GET,
|
|
|
edcb74 |
+ (char *)it);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Allocate memory for ioctl message */
|
|
|
edcb74 |
+ itAllocationLength1 =
|
|
|
edcb74 |
+ (sizeof(ioctl_trans_di) - DI_PAYLOADS_STARTER_LENGTH) +
|
|
|
edcb74 |
+ TSYNC_TMSCL_IN_LEN + TSYNC_TMSCL_MAX_OUT_LEN;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ it1 = (ioctl_trans_di*)alloca(itAllocationLength1);
|
|
|
edcb74 |
+ if (it1 == NULL) {
|
|
|
edcb74 |
+ msyslog(LOG_ERR, "Couldn't allocate transaction memory - Time Scale");
|
|
|
edcb74 |
+ return;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Build CS_GetTimeScale ioctl message */
|
|
|
edcb74 |
+ it1->dest = TSYNC_TMSCL_DEST_ID;
|
|
|
edcb74 |
+ it1->iid = TSYNC_TMSCL_IID;
|
|
|
edcb74 |
+ it1->inPayloadOffset = TSYNC_TMSCL_IN_PYLD_OFF;
|
|
|
edcb74 |
+ it1->inLength = TSYNC_TMSCL_IN_LEN;
|
|
|
edcb74 |
+ it1->outPayloadOffset = TSYNC_TMSCL_OUT_PYLD_OFF;
|
|
|
edcb74 |
+ it1->maxOutLength = TSYNC_TMSCL_MAX_OUT_LEN;
|
|
|
edcb74 |
+ it1->actualOutLength = 0;
|
|
|
edcb74 |
+ it1->status = 0;
|
|
|
edcb74 |
+ memset(it1->payloads, 0, TSYNC_TMSCL_MAX_OUT_LEN);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Read the Time Scale info from the TSYNC-PCI device */
|
|
|
edcb74 |
+ err1 = ioctl(hBoard.file_descriptor,
|
|
|
edcb74 |
+ IOCTL_TSYNC_GET,
|
|
|
edcb74 |
+ (char *)it1);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Allocate memory for ioctl message */
|
|
|
edcb74 |
+ itAllocationLength2 =
|
|
|
edcb74 |
+ (sizeof(ioctl_trans_di) - DI_PAYLOADS_STARTER_LENGTH) +
|
|
|
edcb74 |
+ TSYNC_LEAP_IN_LEN + TSYNC_LEAP_MAX_OUT_LEN;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ it2 = (ioctl_trans_di*)alloca(itAllocationLength2);
|
|
|
edcb74 |
+ if (it2 == NULL) {
|
|
|
edcb74 |
+ msyslog(LOG_ERR, "Couldn't allocate transaction memory - Leap Second");
|
|
|
edcb74 |
+ return;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Build CS_GetLeapSec ioctl message */
|
|
|
edcb74 |
+ it2->dest = TSYNC_LEAP_DEST_ID;
|
|
|
edcb74 |
+ it2->iid = TSYNC_LEAP_IID;
|
|
|
edcb74 |
+ it2->inPayloadOffset = TSYNC_LEAP_IN_PYLD_OFF;
|
|
|
edcb74 |
+ it2->inLength = TSYNC_LEAP_IN_LEN;
|
|
|
edcb74 |
+ it2->outPayloadOffset = TSYNC_LEAP_OUT_PYLD_OFF;
|
|
|
edcb74 |
+ it2->maxOutLength = TSYNC_LEAP_MAX_OUT_LEN;
|
|
|
edcb74 |
+ it2->actualOutLength = 0;
|
|
|
edcb74 |
+ it2->status = 0;
|
|
|
edcb74 |
+ memset(it2->payloads, 0, TSYNC_LEAP_MAX_OUT_LEN);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Read the leap seconds info from the TSYNC-PCI device */
|
|
|
edcb74 |
+ err2 = ioctl(hBoard.file_descriptor,
|
|
|
edcb74 |
+ IOCTL_TSYNC_GET,
|
|
|
edcb74 |
+ (char *)it2);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ pp = peer->procptr;
|
|
|
edcb74 |
+ up = (TsyncUnit*)pp->unitptr;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Read the time from the TSYNC-PCI device */
|
|
|
edcb74 |
+ err3 = ioctl(hBoard.file_descriptor,
|
|
|
edcb74 |
+ IOCTL_TPRO_GET_NTP_TIME,
|
|
|
edcb74 |
+ (char *)&TimeContext);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Close the TSYNC device */
|
|
|
edcb74 |
+ close(hBoard.file_descriptor);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Check for errors
|
|
|
edcb74 |
+ if ((err < 0) ||(err1 < 0) || (err2 < 0) || (err3 < 0) ||
|
|
|
edcb74 |
+ (it->status != 0) || (it1->status != 0) || (it2->status != 0) ||
|
|
|
edcb74 |
+ (it->actualOutLength != TSYNC_REF_OUT_LEN) ||
|
|
|
edcb74 |
+ (it1->actualOutLength != TSYNC_TMSCL_OUT_LEN) ||
|
|
|
edcb74 |
+ (it2->actualOutLength != TSYNC_LEAP_OUT_LEN)) {
|
|
|
edcb74 |
+ refclock_report(peer, CEVNT_FAULT);
|
|
|
edcb74 |
+ return;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Extract reference identifiers from ioctl payload
|
|
|
edcb74 |
+ memset(timeRef, '\0', sizeof(timeRef));
|
|
|
edcb74 |
+ memset(ppsRef, '\0', sizeof(ppsRef));
|
|
|
edcb74 |
+ pRefObj = (void *)it->payloads;
|
|
|
edcb74 |
+ memcpy(timeRef, pRefObj->time, TSYNC_REF_LEN);
|
|
|
edcb74 |
+ memcpy(ppsRef, pRefObj->pps, TSYNC_REF_LEN);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Extract the Clock Service Time Scale and convert to correct byte order
|
|
|
edcb74 |
+ memcpy(&tmscl, it1->payloads, sizeof(tmscl));
|
|
|
edcb74 |
+ tmscl = ntohl(tmscl);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Extract leap second info from ioctl payload and perform byte swapping
|
|
|
edcb74 |
+ for (i = 0; i < (sizeof(leapSec) / 4); i++)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ for (j = 0; j < 4; j++)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ ((unsigned char*)&leapSec)[(i * 4) + j] =
|
|
|
edcb74 |
+ ((unsigned char*)(it2->payloads))[(i * 4) + (3 - j)];
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Determine time reference ID from reference name
|
|
|
edcb74 |
+ for (i = 0; RefIdLookupTbl[i].pRef != NULL; i++)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Search RefID table
|
|
|
edcb74 |
+ if (strstr(timeRef, RefIdLookupTbl[i].pRef) != NULL)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Found the matching string
|
|
|
edcb74 |
+ break;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Determine pps reference ID from reference name
|
|
|
edcb74 |
+ for (j = 0; RefIdLookupTbl[j].pRef != NULL; j++)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Search RefID table
|
|
|
edcb74 |
+ if (strstr(ppsRef, RefIdLookupTbl[j].pRef) != NULL)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Found the matching string
|
|
|
edcb74 |
+ break;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Determine synchronization state from flags
|
|
|
edcb74 |
+ synch = (TimeContext.timeObj.flags == 0x4) ? 1 : 0;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Pull seconds information from time object
|
|
|
edcb74 |
+ seconds = (double) (TimeContext.timeObj.secsDouble);
|
|
|
edcb74 |
+ seconds /= (double) 1000000.0;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /*
|
|
|
edcb74 |
+ ** Convert the number of microseconds to double and then place in the
|
|
|
edcb74 |
+ ** peer's last received long floating point format.
|
|
|
edcb74 |
+ */
|
|
|
edcb74 |
+ DTOLFP(((double)TimeContext.tv.tv_usec / 1000000.0), &pp->lastrec);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /*
|
|
|
edcb74 |
+ ** The specTimeStamp is the number of seconds since 1/1/1970, while the
|
|
|
edcb74 |
+ ** peer's lastrec time should be compatible with NTP which is seconds since
|
|
|
edcb74 |
+ ** 1/1/1900. So Add the number of seconds between 1900 and 1970 to the
|
|
|
edcb74 |
+ ** specTimeStamp and place in the peer's lastrec long floating point struct.
|
|
|
edcb74 |
+ */
|
|
|
edcb74 |
+ pp->lastrec.Ul_i.Xl_ui += (unsigned int)TimeContext.tv.tv_sec +
|
|
|
edcb74 |
+ SECONDS_1900_TO_1970;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ pp->polls++;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /*
|
|
|
edcb74 |
+ ** set the reference clock object
|
|
|
edcb74 |
+ */
|
|
|
edcb74 |
+ sprintf(pp->a_lastcode, "%03d %02d:%02d:%02.6f",
|
|
|
edcb74 |
+ TimeContext.timeObj.days, TimeContext.timeObj.hours,
|
|
|
edcb74 |
+ TimeContext.timeObj.minutes, seconds);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ pp->lencode = strlen (pp->a_lastcode);
|
|
|
edcb74 |
+ pp->day = TimeContext.timeObj.days;
|
|
|
edcb74 |
+ pp->hour = TimeContext.timeObj.hours;
|
|
|
edcb74 |
+ pp->minute = TimeContext.timeObj.minutes;
|
|
|
edcb74 |
+ pp->second = (int) seconds;
|
|
|
edcb74 |
+ seconds = (seconds - (double) (pp->second / 1.0)) * 1000000000;
|
|
|
edcb74 |
+ pp->nsec = (long) seconds;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /*
|
|
|
edcb74 |
+ ** calculate year start
|
|
|
edcb74 |
+ */
|
|
|
edcb74 |
+ jt.year = TimeContext.timeObj.year;
|
|
|
edcb74 |
+ jt.yearday = 1;
|
|
|
edcb74 |
+ jt.monthday = 1;
|
|
|
edcb74 |
+ jt.month = 1;
|
|
|
edcb74 |
+ jt.hour = 0;
|
|
|
edcb74 |
+ jt.minute = 0;
|
|
|
edcb74 |
+ jt.second = 0;
|
|
|
edcb74 |
+ pp->yearstart = caltontp(&jt;;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Calculate and report reference clock offset
|
|
|
edcb74 |
+ offset.l_ui = (long)(((pp->day - 1) * 24) + pp->hour + GMT);
|
|
|
edcb74 |
+ offset.l_ui = (offset.l_ui * 60) + (long)pp->minute;
|
|
|
edcb74 |
+ offset.l_ui = (offset.l_ui * 60) + (long)pp->second;
|
|
|
edcb74 |
+ offset.l_ui = offset.l_ui + (long)pp->yearstart;
|
|
|
edcb74 |
+ offset.l_uf = 0;
|
|
|
edcb74 |
+ DTOLFP(pp->nsec / 1e9, <emp);
|
|
|
edcb74 |
+ L_ADD(&offset, <emp);
|
|
|
edcb74 |
+ refclock_process_offset(pp, offset, pp->lastrec,
|
|
|
edcb74 |
+ pp->fudgetime1);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // KTS in sync
|
|
|
edcb74 |
+ if (synch) {
|
|
|
edcb74 |
+ // Subtract leap second info by one second to determine effective day
|
|
|
edcb74 |
+ ApplyTimeOffset(&(leapSec.utcDate), -1);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // If there is a leap second today and the KTS is using a time scale
|
|
|
edcb74 |
+ // which handles leap seconds then
|
|
|
edcb74 |
+ if ((tmscl != TIME_SCALE_GPS) && (tmscl != TIME_SCALE_TAI) &&
|
|
|
edcb74 |
+ (leapSec.utcDate.year == (unsigned int)TimeContext.timeObj.year) &&
|
|
|
edcb74 |
+ (leapSec.utcDate.doy == (unsigned int)TimeContext.timeObj.days))
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // If adding a second
|
|
|
edcb74 |
+ if (leapSec.offset == 1)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ pp->leap = LEAP_ADDSECOND;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ // Else if removing a second
|
|
|
edcb74 |
+ else if (leapSec.offset == -1)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ pp->leap = LEAP_DELSECOND;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ // Else report no leap second pending (no handling of offsets
|
|
|
edcb74 |
+ // other than +1 or -1)
|
|
|
edcb74 |
+ else
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ pp->leap = LEAP_NOWARNING;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ // Else report no leap second pending
|
|
|
edcb74 |
+ else
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ pp->leap = LEAP_NOWARNING;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ peer->leap = pp->leap;
|
|
|
edcb74 |
+ refclock_report(peer, CEVNT_NOMINAL);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // If reference name reported, then not in holdover
|
|
|
edcb74 |
+ if ((RefIdLookupTbl[i].pRef != NULL) &&
|
|
|
edcb74 |
+ (RefIdLookupTbl[j].pRef != NULL))
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Determine if KTS being synchronized by host (identified as
|
|
|
edcb74 |
+ // "LOCL")
|
|
|
edcb74 |
+ if ((strcmp(RefIdLookupTbl[i].pRefId, TSYNC_REF_LOCAL) == 0) ||
|
|
|
edcb74 |
+ (strcmp(RefIdLookupTbl[j].pRefId, TSYNC_REF_LOCAL) == 0))
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Clear prefer flag
|
|
|
edcb74 |
+ peer->flags &= ~FLAG_PREFER;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Set reference clock stratum level as unusable
|
|
|
edcb74 |
+ pp->stratum = STRATUM_UNSPEC;
|
|
|
edcb74 |
+ peer->stratum = pp->stratum;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // If a valid peer is available
|
|
|
edcb74 |
+ if ((sys_peer != NULL) && (sys_peer != peer))
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Store reference peer stratum level and ID
|
|
|
edcb74 |
+ up->refStratum = sys_peer->stratum;
|
|
|
edcb74 |
+ up->refId = addr2refid(&sys_peer->srcadr);
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ else
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Restore prefer flag
|
|
|
edcb74 |
+ peer->flags |= up->refPrefer;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Store reference stratum as local clock
|
|
|
edcb74 |
+ up->refStratum = TSYNC_LCL_STRATUM;
|
|
|
edcb74 |
+ strncpy((char *)&up->refId, RefIdLookupTbl[j].pRefId,
|
|
|
edcb74 |
+ TSYNC_REF_LEN);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Set reference clock stratum level as local clock
|
|
|
edcb74 |
+ pp->stratum = TSYNC_LCL_STRATUM;
|
|
|
edcb74 |
+ peer->stratum = pp->stratum;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Update reference name
|
|
|
edcb74 |
+ strncpy((char *)&pp->refid, RefIdLookupTbl[j].pRefId,
|
|
|
edcb74 |
+ TSYNC_REF_LEN);
|
|
|
edcb74 |
+ peer->refid = pp->refid;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ // Else in holdover
|
|
|
edcb74 |
+ else
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Restore prefer flag
|
|
|
edcb74 |
+ peer->flags |= up->refPrefer;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Update reference ID to saved ID
|
|
|
edcb74 |
+ pp->refid = up->refId;
|
|
|
edcb74 |
+ peer->refid = pp->refid;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Update stratum level to saved stratum level
|
|
|
edcb74 |
+ pp->stratum = up->refStratum;
|
|
|
edcb74 |
+ peer->stratum = pp->stratum;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+ // Else KTS not in sync
|
|
|
edcb74 |
+ else {
|
|
|
edcb74 |
+ // Place local identifier in peer RefID
|
|
|
edcb74 |
+ strncpy((char *)&pp->refid, TSYNC_REF_LOCAL, TSYNC_REF_LEN);
|
|
|
edcb74 |
+ peer->refid = pp->refid;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Report not in sync
|
|
|
edcb74 |
+ pp->leap = LEAP_NOTINSYNC;
|
|
|
edcb74 |
+ peer->leap = pp->leap;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ if (pp->coderecv == pp->codeproc) {
|
|
|
edcb74 |
+ refclock_report(peer, CEVNT_TIMEOUT);
|
|
|
edcb74 |
+ return;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ record_clock_stats(&peer->srcadr, pp->a_lastcode);
|
|
|
edcb74 |
+ refclock_receive(peer);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ /* Increment the number of times the reference has been polled */
|
|
|
edcb74 |
+ pp->polls++;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} /* End - tsync_poll() */
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+////////////////////////////////////////////////////////////////////////////////
|
|
|
edcb74 |
+// Function: ApplyTimeOffset
|
|
|
edcb74 |
+// Description: The ApplyTimeOffset function adds an offset (in seconds) to a
|
|
|
edcb74 |
+// specified date and time. The specified date and time is passed
|
|
|
edcb74 |
+// back after being modified.
|
|
|
edcb74 |
+//
|
|
|
edcb74 |
+// Assumptions: 1. Every fourth year is a leap year. Therefore, this function
|
|
|
edcb74 |
+// is only accurate through Feb 28, 2100.
|
|
|
edcb74 |
+////////////////////////////////////////////////////////////////////////////////
|
|
|
edcb74 |
+void ApplyTimeOffset(DoyTimeObj* pDt, int off)
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+ SecTimeObj st; // Time, in seconds
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Convert date and time to seconds
|
|
|
edcb74 |
+ SecTimeFromDoyTime(&st, pDt);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Apply offset
|
|
|
edcb74 |
+ st.seconds = (int)((signed long long)st.seconds + (signed long long)off);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Convert seconds to date and time
|
|
|
edcb74 |
+ DoyTimeFromSecTime(pDt, &st);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} // End ApplyTimeOffset
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+////////////////////////////////////////////////////////////////////////////////
|
|
|
edcb74 |
+// Function: SecTimeFromDoyTime
|
|
|
edcb74 |
+// Description: The SecTimeFromDoyTime function converts a specified date
|
|
|
edcb74 |
+// and time into a count of seconds since the base time. This
|
|
|
edcb74 |
+// function operates across the range Base Time to Max Time for
|
|
|
edcb74 |
+// the system.
|
|
|
edcb74 |
+//
|
|
|
edcb74 |
+// Assumptions: 1. A leap year is any year evenly divisible by 4. Therefore,
|
|
|
edcb74 |
+// this function is only accurate through Feb 28, 2100.
|
|
|
edcb74 |
+// 2. Conversion does not account for leap seconds.
|
|
|
edcb74 |
+////////////////////////////////////////////////////////////////////////////////
|
|
|
edcb74 |
+void SecTimeFromDoyTime(SecTimeObj* pSt, DoyTimeObj* pDt)
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+ unsigned int yrs; // Years
|
|
|
edcb74 |
+ unsigned int lyrs; // Leap years
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Start with accumulated time of 0
|
|
|
edcb74 |
+ pSt->seconds = 0;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Calculate the number of years and leap years
|
|
|
edcb74 |
+ yrs = pDt->year - TSYNC_TIME_BASE_YEAR;
|
|
|
edcb74 |
+ lyrs = (yrs + 1) / 4;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Convert leap years and years
|
|
|
edcb74 |
+ pSt->seconds += lyrs * TSYNC_SECS_PER_LYR;
|
|
|
edcb74 |
+ pSt->seconds += (yrs - lyrs) * TSYNC_SECS_PER_YR;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Convert days, hours, minutes and seconds
|
|
|
edcb74 |
+ pSt->seconds += (pDt->doy - 1) * TSYNC_SECS_PER_DAY;
|
|
|
edcb74 |
+ pSt->seconds += pDt->hour * TSYNC_SECS_PER_HR;
|
|
|
edcb74 |
+ pSt->seconds += pDt->minute * TSYNC_SECS_PER_MIN;
|
|
|
edcb74 |
+ pSt->seconds += pDt->second;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Copy the subseconds count
|
|
|
edcb74 |
+ pSt->ns = pDt->ns;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} // End SecTimeFromDoyTime
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+////////////////////////////////////////////////////////////////////////////////
|
|
|
edcb74 |
+// Function: DoyTimeFromSecTime
|
|
|
edcb74 |
+// Description: The DoyTimeFromSecTime function converts a specified count
|
|
|
edcb74 |
+// of seconds since the start of our base time into a SecTimeObj
|
|
|
edcb74 |
+// structure.
|
|
|
edcb74 |
+//
|
|
|
edcb74 |
+// Assumptions: 1. A leap year is any year evenly divisible by 4. Therefore,
|
|
|
edcb74 |
+// this function is only accurate through Feb 28, 2100.
|
|
|
edcb74 |
+// 2. Conversion does not account for leap seconds.
|
|
|
edcb74 |
+////////////////////////////////////////////////////////////////////////////////
|
|
|
edcb74 |
+void DoyTimeFromSecTime(DoyTimeObj* pDt, SecTimeObj* pSt)
|
|
|
edcb74 |
+{
|
|
|
edcb74 |
+ signed long long secs; // Seconds accumulator variable
|
|
|
edcb74 |
+ unsigned int yrs; // Years accumulator variable
|
|
|
edcb74 |
+ unsigned int doys; // Days accumulator variable
|
|
|
edcb74 |
+ unsigned int hrs; // Hours accumulator variable
|
|
|
edcb74 |
+ unsigned int mins; // Minutes accumulator variable
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Convert the seconds count into a signed 64-bit number for calculations
|
|
|
edcb74 |
+ secs = (signed long long)(pSt->seconds);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Calculate the number of 4 year chunks
|
|
|
edcb74 |
+ yrs = (unsigned int)((secs /
|
|
|
edcb74 |
+ ((TSYNC_SECS_PER_YR * 3) + TSYNC_SECS_PER_LYR)) * 4);
|
|
|
edcb74 |
+ secs %= ((TSYNC_SECS_PER_YR * 3) + TSYNC_SECS_PER_LYR);
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // If there is at least a normal year worth of time left
|
|
|
edcb74 |
+ if (secs >= TSYNC_SECS_PER_YR)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Increment the number of years and subtract a normal year of time
|
|
|
edcb74 |
+ yrs++;
|
|
|
edcb74 |
+ secs -= TSYNC_SECS_PER_YR;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // If there is still at least a normal year worth of time left
|
|
|
edcb74 |
+ if (secs >= TSYNC_SECS_PER_YR)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Increment the number of years and subtract a normal year of time
|
|
|
edcb74 |
+ yrs++;
|
|
|
edcb74 |
+ secs -= TSYNC_SECS_PER_YR;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // If there is still at least a leap year worth of time left
|
|
|
edcb74 |
+ if (secs >= TSYNC_SECS_PER_LYR)
|
|
|
edcb74 |
+ {
|
|
|
edcb74 |
+ // Increment the number of years and subtract a leap year of time
|
|
|
edcb74 |
+ yrs++;
|
|
|
edcb74 |
+ secs -= TSYNC_SECS_PER_LYR;
|
|
|
edcb74 |
+ }
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Calculate the day of year as the number of days left, then add 1
|
|
|
edcb74 |
+ // because months start on the 1st.
|
|
|
edcb74 |
+ doys = (unsigned int)((secs / TSYNC_SECS_PER_DAY) + 1);
|
|
|
edcb74 |
+ secs %= TSYNC_SECS_PER_DAY;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Calculate the hour
|
|
|
edcb74 |
+ hrs = (unsigned int)(secs / TSYNC_SECS_PER_HR);
|
|
|
edcb74 |
+ secs %= TSYNC_SECS_PER_HR;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Calculate the minute
|
|
|
edcb74 |
+ mins = (unsigned int)(secs / TSYNC_SECS_PER_MIN);
|
|
|
edcb74 |
+ secs %= TSYNC_SECS_PER_MIN;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+ // Fill in the doytime structure
|
|
|
edcb74 |
+ pDt->year = yrs + TSYNC_TIME_BASE_YEAR;
|
|
|
edcb74 |
+ pDt->doy = doys;
|
|
|
edcb74 |
+ pDt->hour = hrs;
|
|
|
edcb74 |
+ pDt->minute = mins;
|
|
|
edcb74 |
+ pDt->second = (unsigned int)secs;
|
|
|
edcb74 |
+ pDt->ns = pSt->ns;
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+} // End DoyTimeFromSecTime
|
|
|
edcb74 |
+
|
|
|
edcb74 |
+#else
|
|
|
edcb74 |
+int refclock_tsyncpci_bs;
|
|
|
edcb74 |
+#endif /* REFCLOCK */
|