summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/ntpd/refclock_parse.c
diff options
context:
space:
mode:
authorroberto <roberto@FreeBSD.org>2008-08-22 15:58:00 +0000
committerroberto <roberto@FreeBSD.org>2008-08-22 15:58:00 +0000
commitb85c7169a740b2edf0106ad59fdaa1b0160f823c (patch)
tree2b9fb7f64eacb322e95695e412c923e97ba33e88 /contrib/ntp/ntpd/refclock_parse.c
parent1d197cfe9feac6bc29537d8e53c30b6435937b95 (diff)
parent7a6072eb585696f8856cd498c3fd194cf49f14c6 (diff)
downloadFreeBSD-src-b85c7169a740b2edf0106ad59fdaa1b0160f823c.zip
FreeBSD-src-b85c7169a740b2edf0106ad59fdaa1b0160f823c.tar.gz
Merge ntpd & friends 4.2.4p5 from vendor/ntp/dist into head. Next commit
will update usr.sbin/ntp to match this. MFC after: 2 weeks
Diffstat (limited to 'contrib/ntp/ntpd/refclock_parse.c')
-rw-r--r--contrib/ntp/ntpd/refclock_parse.c1521
1 files changed, 1090 insertions, 431 deletions
diff --git a/contrib/ntp/ntpd/refclock_parse.c b/contrib/ntp/ntpd/refclock_parse.c
index 52fadaa..0b0109c 100644
--- a/contrib/ntp/ntpd/refclock_parse.c
+++ b/contrib/ntp/ntpd/refclock_parse.c
@@ -1,32 +1,51 @@
/*
- * /src/NTP/ntp-4/ntpd/refclock_parse.c,v 4.36 1999/11/28 17:18:20 kardel RELEASE_19991128_A
+ * /src/NTP/REPOSITORY/ntp4-dev/ntpd/refclock_parse.c,v 4.80 2007/08/11 12:06:29 kardel Exp
*
- * refclock_parse.c,v 4.36 1999/11/28 17:18:20 kardel RELEASE_19991128_A
+ * refclock_parse.c,v 4.80 2007/08/11 12:06:29 kardel Exp
*
- * generic reference clock driver for receivers
+ * generic reference clock driver for several DCF/GPS/MSF/... receivers
*
- * optionally make use of a STREAMS module for input processing where
- * available and configured. Currently the STREAMS module
- * is only available for Suns running SunOS 4.x and SunOS5.x
+ * PPS notes:
+ * On systems that support PPSAPI (RFC2783) PPSAPI is the
+ * preferred interface.
*
- * the STREAMS module is not required for operation and may be omitted
- * at the cost of reduced accuracy. As new kernel interfaces emerger this
- * restriction may be lifted in future.
+ * Optionally make use of a STREAMS module for input processing where
+ * available and configured. This STREAMS module reduces the time
+ * stamp latency for serial and PPS events.
+ * Currently the STREAMS module is only available for Suns running
+ * SunOS 4.x and SunOS5.x.
*
- * Copyright (c) 1995-1999 by Frank Kardel <kardel@acm.org>
+ * Copyright (c) 1995-2007 by Frank Kardel <kardel <AT> ntp.org>
* Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
*
- * This software may not be sold for profit without a written consent
- * from the author.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*
*/
#ifdef HAVE_CONFIG_H
-# include <config.h>
+# include "config.h"
#endif
#if defined(REFCLOCK) && defined(CLOCK_PARSE)
@@ -42,12 +61,12 @@
* - Schmid clock (DCF)
* - Conrad DCF77 receiver module (DCF)
* - FAU DCF77 NTP receiver (TimeBrick) (DCF)
+ * - WHARTON 400A Series clock (DCF)
*
* - Meinberg GPS166/GPS167 (GPS)
* - Trimble (TSIP and TAIP protocol) (GPS)
*
* - RCC8000 MSF Receiver (MSF)
- * - WHARTON 400A Series clock (DCF)
* - VARITEXT clock (MSF)
*/
@@ -79,6 +98,7 @@
#include "ntp_refclock.h"
#include "ntp_unixtime.h" /* includes <sys/time.h> */
#include "ntp_control.h"
+#include "ntp_string.h"
#include <stdio.h>
#include <ctype.h>
@@ -86,6 +106,10 @@
# include <time.h>
#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
#if !defined(STREAM) && !defined(HAVE_SYSV_TTYS) && !defined(HAVE_BSD_TTYS) && !defined(HAVE_TERMIOS)
# include "Bletch: Define one of {STREAM,HAVE_SYSV_TTYS,HAVE_TERMIOS}"
#endif
@@ -115,14 +139,43 @@
# include <sys/ioctl.h>
#endif
+#ifdef HAVE_PPSAPI
+# include "ppsapi_timepps.h"
+#endif
+
#ifdef PPS
-#ifdef HAVE_SYS_PPSCLOCK_H
-#include <sys/ppsclock.h>
+# ifdef HAVE_SYS_PPSCLOCK_H
+# include <sys/ppsclock.h>
+# endif
+# ifdef HAVE_TIO_SERIAL_STUFF
+# include <linux/serial.h>
+# endif
+#endif
+
+#define BUFFER_SIZE(_BUF, _PTR) ((_BUF) + sizeof(_BUF) - (_PTR))
+#define BUFFER_SIZES(_BUF, _PTR, _SZ) ((_BUF) + (_SZ) - (_PTR))
+
+/*
+ * document type of PPS interfacing - copy of ifdef mechanism in local_input()
+ */
+#undef PPS_METHOD
+
+#ifdef HAVE_PPSAPI
+#define PPS_METHOD "PPS API"
+#else
+#ifdef TIOCDCDTIMESTAMP
+#define PPS_METHOD "TIOCDCDTIMESTAMP"
+#else /* TIOCDCDTIMESTAMP */
+#if defined(HAVE_STRUCT_PPSCLOCKEV) && (defined(HAVE_CIOGETEV) || defined(HAVE_TIOCGPPSEV))
+#ifdef HAVE_CIOGETEV
+#define PPS_METHOD "CIOGETEV"
#endif
-#ifdef HAVE_TIO_SERIAL_STUFF
-#include <linux/serial.h>
+#ifdef HAVE_TIOCGPPSEV
+#define PPS_METHOD "TIOCGPPSEV"
#endif
#endif
+#endif /* TIOCDCDTIMESTAMP */
+#endif /* HAVE_PPSAPI */
#include "ntp_io.h"
#include "ntp_stdlib.h"
@@ -133,28 +186,26 @@
#include "binio.h"
#include "ascii.h"
#include "ieee754io.h"
+#include "recvbuff.h"
-static char rcsid[]="refclock_parse.c,v 4.36 1999/11/28 17:18:20 kardel RELEASE_19991128_A";
+static char rcsid[] = "refclock_parse.c,v 4.80 2007/08/11 12:06:29 kardel Exp";
/**===========================================================================
** external interface to ntp mechanism
**/
-static void parse_init P((void));
static int parse_start P((int, struct peer *));
static void parse_shutdown P((int, struct peer *));
static void parse_poll P((int, struct peer *));
static void parse_control P((int, struct refclockstat *, struct refclockstat *, struct peer *));
-#define parse_buginfo noentry
-
struct refclock refclock_parse = {
parse_start,
parse_shutdown,
parse_poll,
parse_control,
- parse_init,
- parse_buginfo,
+ noentry,
+ noentry,
NOFLAGS
};
@@ -163,10 +214,14 @@ struct refclock refclock_parse = {
*/
#define MAXUNITS 4 /* maximum number of "PARSE" units permitted */
#define PARSEDEVICE "/dev/refclock-%d" /* device to open %d is unit number */
+#define PARSEPPSDEVICE "/dev/refclockpps-%d" /* optional pps device to open %d is unit number */
#undef ABS
#define ABS(_X_) (((_X_) < 0) ? -(_X_) : (_X_))
+#define PARSE_HARDPPS_DISABLE 0
+#define PARSE_HARDPPS_ENABLE 1
+
/**===========================================================================
** function vector for dynamically binding io handling mechanism
**/
@@ -344,9 +399,17 @@ struct parseunit
u_long pollneeddata; /* current_time(!=0) for receive sample expected in PPS mode */
u_short lastformat; /* last format used */
u_long lastsync; /* time (ntp) when clock was last seen fully synchronized */
- u_long lastmissed; /* time (ntp) when poll didn't get data (powerup heuristic) */
+ u_long maxunsync; /* max time in seconds a receiver is trusted after loosing synchronisation */
+ double ppsphaseadjust; /* phase adjustment of PPS time stamp */
+ u_long lastmissed; /* time (ntp) when poll didn't get data (powerup heuristic) */
u_long ppsserial; /* magic cookie for ppsclock serials (avoids stale ppsclock data) */
- parsetime_t time; /* last (parse module) data */
+ int ppsfd; /* fd to ise for PPS io */
+#ifdef HAVE_PPSAPI
+ pps_handle_t ppshandle; /* store PPSAPI handle */
+ pps_params_t ppsparams; /* current PPS parameters */
+ int hardppsstate; /* current hard pps state */
+#endif
+ parsetime_t timedata; /* last (parse module) data */
void *localdata; /* optional local, receiver-specific data */
unsigned long localstate; /* private local state */
struct errorinfo errors[ERR_CNT]; /* error state table for suppressing excessive error messages */
@@ -376,7 +439,7 @@ typedef struct poll_info
#define NO_INIT 0
#define NO_END 0
#define NO_EVENT 0
-#define NO_DATA 0
+#define NO_LCLDATA 0
#define NO_MESSAGE 0
#define NO_PPSDELAY 0
@@ -397,7 +460,7 @@ typedef struct poll_info
#define NOCLOCK_POLL NO_POLL
#define NOCLOCK_INIT NO_INIT
#define NOCLOCK_END NO_END
-#define NOCLOCK_DATA NO_DATA
+#define NOCLOCK_DATA NO_LCLDATA
#define NOCLOCK_FORMAT ""
#define NOCLOCK_TYPE CTL_SST_TS_UNSPEC
#define NOCLOCK_SAMPLES 0
@@ -410,7 +473,7 @@ typedef struct poll_info
* receiver specific constants
*/
#define MBG_SPEED (B9600)
-#define MBG_CFLAG (CS7|PARENB|CREAD|CLOCAL|HUPCL)
+#define MBG_CFLAG (CS7|PARENB|CREAD|CLOCAL|HUPCL|CSTOPB)
#define MBG_IFLAG (IGNBRK|IGNPAR|ISTRIP)
#define MBG_OFLAG 0
#define MBG_LFLAG 0
@@ -591,6 +654,11 @@ static poll_info_t wsdcf_pollinfo = { WS_POLLRATE, WS_POLLCMD, WS_CMDSIZE };
#define CONRAD_BASEDELAY 0.292 /* Conrad receiver @ 50 Baud on a Sun */
#define CONRAD_DESCRIPTION "RAW DCF77 CODE (Conrad DCF77 receiver module)"
+/* Gude Analog- und Digitalsystem GmbH 'Expert mouseCLOCK USB v2.0' */
+#define GUDE_EMC_USB_V20_SPEED (B4800)
+#define GUDE_EMC_USB_V20_BASEDELAY 0.425 /* USB serial<->USB converter FTDI232R */
+#define GUDE_EMC_USB_V20_DESCRIPTION "RAW DCF77 CODE (Expert mouseCLOCK USB v2.0)"
+
/*
* TimeBrick receiver
*/
@@ -645,6 +713,7 @@ static void trimbletsip_message P((struct parseunit *, parsetime_t *));
static void trimbletsip_event P((struct parseunit *, int));
#define TRIMBLETSIP_IDLE_TIME (300) /* 5 minutes silence at most */
+#define TRIMBLE_RESET_HOLDOFF TRIMBLETSIP_IDLE_TIME
#define TRIMBLETAIP_SPEED (B4800)
#define TRIMBLETAIP_CFLAG (CS8|CREAD|CLOCAL)
@@ -819,7 +888,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
DCFPZF535_ROOTDELAY,
DCFPZF535_BASEDELAY,
DCF_P_ID,
@@ -842,7 +911,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
DCFPZF535OCXO_ROOTDELAY,
DCFPZF535OCXO_BASEDELAY,
DCF_P_ID,
@@ -865,7 +934,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
DCFUA31_ROOTDELAY,
DCFUA31_BASEDELAY,
DCF_A_ID,
@@ -888,7 +957,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
DCF7000_ROOTDELAY,
DCF7000_BASEDELAY,
DCF_A_ID,
@@ -934,7 +1003,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
RAWDCF_ROOTDELAY,
CONRAD_BASEDELAY,
DCF_A_ID,
@@ -957,7 +1026,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
RAWDCF_ROOTDELAY,
TIMEBRICK_BASEDELAY,
DCF_A_ID,
@@ -1003,7 +1072,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
RAWDCF_ROOTDELAY,
IGELCLOCK_BASEDELAY,
DCF_A_ID,
@@ -1103,7 +1172,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
HOPF6021_ROOTDELAY,
HOPF6021_BASEDELAY,
DCF_ID,
@@ -1126,7 +1195,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
COMPUTIME_ROOTDELAY,
COMPUTIME_BASEDELAY,
COMPUTIME_ID,
@@ -1149,7 +1218,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
RAWDCF_ROOTDELAY,
RAWDCF_BASEDELAY,
DCF_A_ID,
@@ -1172,7 +1241,7 @@ static struct parse_clockinfo
NO_EVENT, /* special event handling (e.g. reset clock) */
NO_END, /* active poll end routine */
NO_MESSAGE, /* process a lower layer message */
- NO_DATA, /* local data area for "poll" mechanism */
+ NO_LCLDATA, /* local data area for "poll" mechanism */
0, /* rootdelay */
11.0 /* bits */ / 9600, /* current offset by which the RS232
time code is delayed from the actual time */
@@ -1197,7 +1266,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
RAWDCF_ROOTDELAY,
RAWDCF_BASEDELAY,
DCF_A_ID,
@@ -1220,7 +1289,7 @@ static struct parse_clockinfo
NO_EVENT,
NO_END,
NO_MESSAGE,
- NO_DATA,
+ NO_LCLDATA,
VARITEXT_ROOTDELAY,
VARITEXT_BASEDELAY,
VARITEXT_ID,
@@ -1235,7 +1304,53 @@ static struct parse_clockinfo
VARITEXT_LFLAG,
VARITEXT_SAMPLES,
VARITEXT_KEEP
- }
+ },
+ { /* mode 18 */
+ MBG_FLAGS,
+ NO_POLL,
+ NO_INIT,
+ NO_EVENT,
+ GPS16X_END,
+ GPS16X_MESSAGE,
+ GPS16X_DATA,
+ GPS16X_ROOTDELAY,
+ GPS16X_BASEDELAY,
+ GPS16X_ID,
+ GPS16X_DESCRIPTION,
+ GPS16X_FORMAT,
+ GPS_TYPE,
+ GPS16X_MAXUNSYNC,
+ GPS16X_SPEED,
+ GPS16X_CFLAG,
+ GPS16X_IFLAG,
+ GPS16X_OFLAG,
+ GPS16X_LFLAG,
+ GPS16X_SAMPLES,
+ GPS16X_KEEP
+ },
+ { /* mode 19 */
+ RAWDCF_FLAGS,
+ NO_POLL,
+ RAWDCF_INIT,
+ NO_EVENT,
+ NO_END,
+ NO_MESSAGE,
+ NO_LCLDATA,
+ RAWDCF_ROOTDELAY,
+ GUDE_EMC_USB_V20_BASEDELAY,
+ DCF_A_ID,
+ GUDE_EMC_USB_V20_DESCRIPTION,
+ RAWDCF_FORMAT,
+ DCF_TYPE,
+ RAWDCF_MAXUNSYNC,
+ GUDE_EMC_USB_V20_SPEED,
+ RAWDCF_CFLAG,
+ RAWDCF_IFLAG,
+ RAWDCF_OFLAG,
+ RAWDCF_LFLAG,
+ RAWDCF_SAMPLES,
+ RAWDCF_KEEP
+ },
};
static int ncltypes = sizeof(parse_clockinfo) / sizeof(struct parse_clockinfo);
@@ -1252,8 +1367,6 @@ static int ncltypes = sizeof(parse_clockinfo) / sizeof(struct parse_clockinfo);
#define PARSESTATISTICS (60*60) /* output state statistics every hour */
-static struct parseunit *parseunits[MAXUNITS];
-
static int notice = 0;
#define PARSE_STATETIME(parse, i) ((parse->generic->currentstatus == i) ? parse->statetime[i] + current_time - parse->lastchange : parse->statetime[i])
@@ -1551,8 +1664,8 @@ ppsclock_init(
* now push the parse streams module
* it will ensure exclusive access to the device
*/
- if (ioctl(parse->generic->io.fd, I_PUSH, (caddr_t)m1) == -1 &&
- ioctl(parse->generic->io.fd, I_PUSH, (caddr_t)m2) == -1)
+ if (ioctl(parse->ppsfd, I_PUSH, (caddr_t)m1) == -1 &&
+ ioctl(parse->ppsfd, I_PUSH, (caddr_t)m2) == -1)
{
if (errno != EINVAL)
{
@@ -1563,7 +1676,7 @@ ppsclock_init(
}
if (!local_init(parse))
{
- (void)ioctl(parse->generic->io.fd, I_POP, (caddr_t)0);
+ (void)ioctl(parse->ppsfd, I_POP, (caddr_t)0);
return 0;
}
@@ -1790,7 +1903,6 @@ stream_receive(
ERR(ERR_BADIO)
msyslog(LOG_ERR,"PARSE receiver #%d: stream_receive: bad size (got %d expected %d)",
CLK_UNIT(parse->peer), rbufp->recv_length, (int)sizeof(parsetime_t));
- parse->generic->baddata++;
parse_event(parse, CEVNT_BADREPLY);
return;
}
@@ -1807,12 +1919,12 @@ stream_receive(
CLK_UNIT(parse->peer),
(unsigned int)parsetime.parse_status,
(unsigned int)parsetime.parse_state,
- (long)parsetime.parse_time.tv.tv_sec,
- (long)parsetime.parse_time.tv.tv_usec,
- (long)parsetime.parse_stime.tv.tv_sec,
- (long)parsetime.parse_stime.tv.tv_usec,
- (long)parsetime.parse_ptime.tv.tv_sec,
- (long)parsetime.parse_ptime.tv.tv_usec);
+ (unsigned long)parsetime.parse_time.tv.tv_sec,
+ (unsigned long)parsetime.parse_time.tv.tv_usec,
+ (unsigned long)parsetime.parse_stime.tv.tv_sec,
+ (unsigned long)parsetime.parse_stime.tv.tv_usec,
+ (unsigned long)parsetime.parse_ptime.tv.tv_sec,
+ (unsigned long)parsetime.parse_ptime.tv.tv_usec);
}
#endif
@@ -1945,17 +2057,96 @@ local_input(
{
if (parse_ioread(&parse->parseio, (unsigned int)(*s++), &ts))
{
- struct recvbuf buf;
+ struct recvbuf *buf;
/*
* got something good to eat
*/
if (!PARSE_PPS(parse->parseio.parse_dtime.parse_state))
{
+#ifdef HAVE_PPSAPI
+ if (parse->flags & PARSE_PPSCLOCK)
+ {
+ struct timespec pps_timeout;
+ pps_info_t pps_info;
+
+ pps_timeout.tv_sec = 0;
+ pps_timeout.tv_nsec = 0;
+
+ if (time_pps_fetch(parse->ppshandle, PPS_TSFMT_TSPEC, &pps_info,
+ &pps_timeout) == 0)
+ {
+ if (pps_info.assert_sequence + pps_info.clear_sequence != parse->ppsserial)
+ {
+ double dtemp;
+
+ struct timespec pts;
+ /*
+ * add PPS time stamp if available via ppsclock module
+ * and not supplied already.
+ */
+ if (parse->flags & PARSE_CLEAR)
+ pts = pps_info.clear_timestamp;
+ else
+ pts = pps_info.assert_timestamp;
+
+ parse->parseio.parse_dtime.parse_ptime.fp.l_ui = pts.tv_sec + JAN_1970;
+
+ dtemp = pts.tv_nsec / 1e9;
+ if (dtemp < 0.) {
+ dtemp += 1;
+ parse->parseio.parse_dtime.parse_ptime.fp.l_ui--;
+ }
+ if (dtemp > 1.) {
+ dtemp -= 1;
+ parse->parseio.parse_dtime.parse_ptime.fp.l_ui++;
+ }
+ parse->parseio.parse_dtime.parse_ptime.fp.l_uf = dtemp * FRAC;
+
+ parse->parseio.parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
+#ifdef DEBUG
+ if (debug > 3)
+ {
+ printf(
+ "parse: local_receive: fd %d PPSAPI seq %ld - PPS %s\n",
+ rbufp->fd,
+ (long)pps_info.assert_sequence + (long)pps_info.clear_sequence,
+ lfptoa(&parse->parseio.parse_dtime.parse_ptime.fp, 6));
+ }
+#endif
+ }
+#ifdef DEBUG
+ else
+ {
+ if (debug > 3)
+ {
+ printf(
+ "parse: local_receive: fd %d PPSAPI seq assert %ld, seq clear %ld - NO PPS event\n",
+ rbufp->fd,
+ (long)pps_info.assert_sequence, (long)pps_info.clear_sequence);
+ }
+ }
+#endif
+ parse->ppsserial = pps_info.assert_sequence + pps_info.clear_sequence;
+ }
+#ifdef DEBUG
+ else
+ {
+ if (debug > 3)
+ {
+ printf(
+ "parse: local_receive: fd %d PPSAPI time_pps_fetch errno = %d\n",
+ rbufp->fd,
+ errno);
+ }
+ }
+#endif
+ }
+#else
#ifdef TIOCDCDTIMESTAMP
struct timeval dcd_time;
- if (ioctl(rbufp->fd, TIOCDCDTIMESTAMP, &dcd_time) != -1)
+ if (ioctl(parse->ppsfd, TIOCDCDTIMESTAMP, &dcd_time) != -1)
{
l_fp tstmp;
@@ -1969,7 +2160,7 @@ local_input(
{
printf(
"parse: local_receive: fd %d DCDTIMESTAMP %s\n",
- rbufp->fd,
+ parse->ppsfd,
lfptoa(&tstmp, 6));
printf(" sigio %s\n",
lfptoa(&ts.fp, 6));
@@ -1982,54 +2173,58 @@ local_input(
#else /* TIOCDCDTIMESTAMP */
#if defined(HAVE_STRUCT_PPSCLOCKEV) && (defined(HAVE_CIOGETEV) || defined(HAVE_TIOCGPPSEV))
if (parse->flags & PARSE_PPSCLOCK)
- {
- l_fp tts;
- struct ppsclockev ev;
+ {
+ l_fp tts;
+ struct ppsclockev ev;
#ifdef HAVE_CIOGETEV
- if (ioctl(parse->generic->io.fd, CIOGETEV, (caddr_t)&ev) == 0)
+ if (ioctl(parse->ppsfd, CIOGETEV, (caddr_t)&ev) == 0)
#endif
#ifdef HAVE_TIOCGPPSEV
- if (ioctl(parse->generic->io.fd, TIOCGPPSEV, (caddr_t)&ev) == 0)
+ if (ioctl(parse->ppsfd, TIOCGPPSEV, (caddr_t)&ev) == 0)
#endif
{
- if (ev.serial != parse->ppsserial)
+ if (ev.serial != parse->ppsserial)
+ {
+ /*
+ * add PPS time stamp if available via ppsclock module
+ * and not supplied already.
+ */
+ if (!buftvtots((const char *)&ev.tv, &tts))
{
- /*
- * add PPS time stamp if available via ppsclock module
- * and not supplied already.
- */
- if (!buftvtots((const char *)&ev.tv, &tts))
- {
- ERR(ERR_BADDATA)
- msyslog(LOG_ERR,"parse: local_receive: timestamp conversion error (buftvtots) (ppsclockev.tv)");
- }
- else
- {
- parse->parseio.parse_dtime.parse_ptime.fp = tts;
- parse->parseio.parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
- }
+ ERR(ERR_BADDATA)
+ msyslog(LOG_ERR,"parse: local_receive: timestamp conversion error (buftvtots) (ppsclockev.tv)");
+ }
+ else
+ {
+ parse->parseio.parse_dtime.parse_ptime.fp = tts;
+ parse->parseio.parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
}
- parse->ppsserial = ev.serial;
+ }
+ parse->ppsserial = ev.serial;
}
- }
+ }
#endif
#endif /* TIOCDCDTIMESTAMP */
+#endif /* !HAVE_PPSAPI */
}
if (count)
{ /* simulate receive */
- memmove((caddr_t)buf.recv_buffer,
- (caddr_t)&parse->parseio.parse_dtime,
- sizeof(parsetime_t));
+ buf = get_free_recv_buffer();
+ if (buf != NULL) {
+ memmove((caddr_t)buf->recv_buffer,
+ (caddr_t)&parse->parseio.parse_dtime,
+ sizeof(parsetime_t));
+ buf->recv_length = sizeof(parsetime_t);
+ buf->recv_time = rbufp->recv_time;
+ buf->srcadr = rbufp->srcadr;
+ buf->dstadr = rbufp->dstadr;
+ buf->receiver = rbufp->receiver;
+ buf->fd = rbufp->fd;
+ buf->X_from_where = rbufp->X_from_where;
+ add_full_recv_buffer(buf);
+ }
parse_iodone(&parse->parseio);
- buf.recv_length = sizeof(parsetime_t);
- buf.recv_time = rbufp->recv_time;
- buf.srcadr = rbufp->srcadr;
- buf.dstadr = rbufp->dstadr;
- buf.fd = rbufp->fd;
- buf.next = 0;
- buf.X_from_where = rbufp->X_from_where;
- rbufp->receiver(&buf);
}
else
{
@@ -2064,7 +2259,6 @@ local_receive(
ERR(ERR_BADIO)
msyslog(LOG_ERR,"PARSE receiver #%d: local_receive: bad size (got %d expected %d)",
CLK_UNIT(parse->peer), rbufp->recv_length, (int)sizeof(parsetime_t));
- parse->generic->baddata++;
parse_event(parse, CEVNT_BADREPLY);
return;
}
@@ -2077,16 +2271,16 @@ local_receive(
#ifdef DEBUG
if (debug > 3)
{
- printf("PARSE receiver #%d: status %06x, state %08x, time %lx.%08lx, stime %lx.%08lx, ptime %lx.%08lx\n",
+ printf("PARSE receiver #%d: status %06x, state %08x, time(fp) %lx.%08lx, stime(fp) %lx.%08lx, ptime(fp) %lx.%08lx\n",
CLK_UNIT(parse->peer),
(unsigned int)parsetime.parse_status,
(unsigned int)parsetime.parse_state,
- (long)parsetime.parse_time.tv.tv_sec,
- (long)parsetime.parse_time.tv.tv_usec,
- (long)parsetime.parse_stime.tv.tv_sec,
- (long)parsetime.parse_stime.tv.tv_usec,
- (long)parsetime.parse_ptime.tv.tv_sec,
- (long)parsetime.parse_ptime.tv.tv_usec);
+ (unsigned long)parsetime.parse_time.fp.l_ui,
+ (unsigned long)parsetime.parse_time.fp.l_uf,
+ (unsigned long)parsetime.parse_stime.fp.l_ui,
+ (unsigned long)parsetime.parse_stime.fp.l_uf,
+ (unsigned long)parsetime.parse_ptime.fp.l_ui,
+ (unsigned long)parsetime.parse_ptime.fp.l_uf);
}
#endif
@@ -2124,7 +2318,8 @@ init_iobinding(
static char *
parsestate(
u_long lstate,
- char *buffer
+ char *buffer,
+ int size
)
{
static struct bits
@@ -2161,31 +2356,35 @@ parsestate(
{ 0 }
};
int i;
+ char *s, *t;
+
*buffer = '\0';
+ s = t = buffer;
i = 0;
while (flagstrings[i].bit)
{
if (flagstrings[i].bit & lstate)
{
- if (buffer[0])
- strcat(buffer, "; ");
- strcat(buffer, flagstrings[i].name);
+ if (s != t)
+ strncpy(t, "; ", BUFFER_SIZES(buffer, t, size));
+ strncat(t, flagstrings[i].name, BUFFER_SIZES(buffer, t, size));
+ t += strlen(t);
}
i++;
}
if (lstate & (PARSEB_S_LEAP|PARSEB_S_ANTENNA|PARSEB_S_PPS|PARSEB_S_POSITION))
{
- char *s, *t;
+ if (s != t)
+ strncpy(t, "; ", BUFFER_SIZES(buffer, t, size));
- if (buffer[0])
- strcat(buffer, "; ");
+ t += strlen(t);
- strcat(buffer, "(");
+ strncpy(t, "(", BUFFER_SIZES(buffer, t, size));
- t = s = buffer + strlen(buffer);
+ s = t = t + strlen(t);
i = 0;
while (sflagstrings[i].bit)
@@ -2194,16 +2393,16 @@ parsestate(
{
if (t != s)
{
- strcpy(t, "; ");
+ strncpy(t, "; ", BUFFER_SIZES(buffer, t, size));
t += 2;
}
- strcpy(t, sflagstrings[i].name);
+ strncpy(t, sflagstrings[i].name, BUFFER_SIZES(buffer, t, size));
t += strlen(t);
}
i++;
}
- strcpy(t, ")");
+ strncpy(t, ")", BUFFER_SIZES(buffer, t, size));
}
return buffer;
}
@@ -2214,7 +2413,8 @@ parsestate(
static char *
parsestatus(
u_long lstate,
- char *buffer
+ char *buffer,
+ int size
)
{
static struct bits
@@ -2242,8 +2442,8 @@ parsestatus(
if (flagstrings[i].bit & lstate)
{
if (buffer[0])
- strcat(buffer, "; ");
- strcat(buffer, flagstrings[i].name);
+ strncat(buffer, "; ", size);
+ strncat(buffer, flagstrings[i].name, size);
}
i++;
}
@@ -2287,7 +2487,7 @@ clockstatus(
i++;
}
- sprintf(buffer, "unknown #%ld", (u_long)lstate);
+ snprintf(buffer, sizeof(buffer), "unknown #%ld", (u_long)lstate);
return buffer;
}
@@ -2303,12 +2503,13 @@ l_mktime(
{
u_long tmp, m, s;
static char buffer[40];
+ char *t;
buffer[0] = '\0';
if ((tmp = delta / (60*60*24)) != 0)
{
- sprintf(buffer, "%ldd+", (u_long)tmp);
+ snprintf(buffer, BUFFER_SIZE(buffer, buffer), "%ldd+", (u_long)tmp);
delta -= tmp * 60*60*24;
}
@@ -2317,8 +2518,10 @@ l_mktime(
m = delta % 60;
delta /= 60;
- sprintf(buffer+strlen(buffer), "%02d:%02d:%02d",
- (int)delta, (int)m, (int)s);
+ t = buffer + strlen(buffer);
+
+ snprintf(t, BUFFER_SIZE(buffer, t), "%02d:%02d:%02d",
+ (int)delta, (int)m, (int)s);
return buffer;
}
@@ -2377,7 +2580,7 @@ parse_statistics(
*/
static void
cparse_statistics(
- register struct parseunit *parse
+ struct parseunit *parse
)
{
if (parse->laststatistic + PARSESTATISTICS < current_time)
@@ -2390,16 +2593,6 @@ cparse_statistics(
**/
/*--------------------------------------------------
- * parse_init - initialize internal parse driver data
- */
-static void
-parse_init(void)
-{
- memset((caddr_t)parseunits, 0, sizeof parseunits);
-}
-
-
-/*--------------------------------------------------
* parse_shutdown - shut down a PARSE clock
*/
static void
@@ -2408,15 +2601,32 @@ parse_shutdown(
struct peer *peer
)
{
- struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr;
+ struct parseunit *parse = (struct parseunit *)0;
+
+ if (peer && peer->procptr)
+ parse = (struct parseunit *)peer->procptr->unitptr;
- if (parse && !parse->peer)
+ if (!parse)
{
- msyslog(LOG_ERR,
- "PARSE receiver #%d: parse_shutdown: INTERNAL ERROR, unit not in use", unit);
+ /* nothing to clean up */
return;
}
+ if (!parse->peer)
+ {
+ msyslog(LOG_INFO, "PARSE receiver #%d: INTERNAL ERROR - unit already inactive - shutdown ignored", unit);
+ return;
+ }
+
+#ifdef HAVE_PPSAPI
+ if (parse->flags & PARSE_PPSCLOCK)
+ {
+ (void)time_pps_destroy(parse->ppshandle);
+ }
+#endif
+ if (parse->generic->io.fd != parse->ppsfd && parse->ppsfd != -1)
+ (void)close(parse->ppsfd); /* close separate PPS source */
+
/*
* print statistics a last time and
* stop statistics machine
@@ -2428,6 +2638,9 @@ parse_shutdown(
parse->parse_type->cl_end(parse);
}
+ /*
+ * cleanup before leaving this world
+ */
if (parse->binding)
PARSE_END(parse);
@@ -2443,9 +2656,138 @@ parse_shutdown(
CLK_UNIT(parse->peer), parse->parse_type->cl_description);
parse->peer = (struct peer *)0; /* unused now */
+ peer->procptr->unitptr = (caddr_t)0;
free(parse);
}
+#ifdef HAVE_PPSAPI
+/*----------------------------------------
+ * set up HARDPPS via PPSAPI
+ */
+static void
+parse_hardpps(
+ struct parseunit *parse,
+ int mode
+ )
+{
+ if (parse->hardppsstate == mode)
+ return;
+
+ if (CLK_PPS(parse->peer) && (parse->flags & PARSE_PPSKERNEL)) {
+ int i = 0;
+
+ if (mode == PARSE_HARDPPS_ENABLE)
+ {
+ if (parse->flags & PARSE_CLEAR)
+ i = PPS_CAPTURECLEAR;
+ else
+ i = PPS_CAPTUREASSERT;
+ }
+
+ if (time_pps_kcbind(parse->ppshandle, PPS_KC_HARDPPS, i,
+ PPS_TSFMT_TSPEC) < 0) {
+ msyslog(LOG_ERR, "PARSE receiver #%d: time_pps_kcbind failed: %m",
+ CLK_UNIT(parse->peer));
+ } else {
+ NLOG(NLOG_CLOCKINFO)
+ msyslog(LOG_INFO, "PARSE receiver #%d: kernel PPS synchronisation %sabled",
+ CLK_UNIT(parse->peer), (mode == PARSE_HARDPPS_ENABLE) ? "en" : "dis");
+ /*
+ * tell the rest, that we have a kernel PPS source, iff we ever enable HARDPPS
+ */
+ if (mode == PARSE_HARDPPS_ENABLE)
+ pps_enable = 1;
+ }
+ }
+
+ parse->hardppsstate = mode;
+}
+
+/*----------------------------------------
+ * set up PPS via PPSAPI
+ */
+static int
+parse_ppsapi(
+ struct parseunit *parse
+ )
+{
+ int cap, mode, mode1;
+ char *cp;
+
+ parse->flags &= ~PARSE_PPSCLOCK;
+
+ if (time_pps_getcap(parse->ppshandle, &cap) < 0) {
+ msyslog(LOG_ERR, "PARSE receiver #%d: parse_ppsapi: time_pps_getcap failed: %m",
+ CLK_UNIT(parse->peer));
+
+ return 0;
+ }
+
+ if (time_pps_getparams(parse->ppshandle, &parse->ppsparams) < 0) {
+ msyslog(LOG_ERR, "PARSE receiver #%d: parse_ppsapi: time_pps_getparams failed: %m",
+ CLK_UNIT(parse->peer));
+ return 0;
+ }
+
+ /* nb. only turn things on, if someone else has turned something
+ * on before we get here, leave it alone!
+ */
+
+ if (parse->flags & PARSE_CLEAR) {
+ cp = "CLEAR";
+ mode = PPS_CAPTURECLEAR;
+ mode1 = PPS_OFFSETCLEAR;
+ } else {
+ cp = "ASSERT";
+ mode = PPS_CAPTUREASSERT;
+ mode1 = PPS_OFFSETASSERT;
+ }
+
+ msyslog(LOG_INFO, "PARSE receiver #%d: initializing PPS to %s",
+ CLK_UNIT(parse->peer), cp);
+
+ if (!(mode & cap)) {
+ msyslog(LOG_ERR, "PARSE receiver #%d: FAILED to initialize PPS to %s (PPS API capabilities=0x%x)",
+ CLK_UNIT(parse->peer), cp, cap);
+
+ return 0;
+ }
+
+ if (!(mode1 & cap)) {
+ msyslog(LOG_WARNING, "PARSE receiver #%d: Cannot set PPS_%sCLEAR, this will increase jitter (PPS API capabilities=0x%x)",
+ CLK_UNIT(parse->peer), cp, cap);
+ mode1 = 0;
+ } else {
+ if (mode1 == PPS_OFFSETCLEAR)
+ {
+ parse->ppsparams.clear_offset.tv_sec = -parse->ppsphaseadjust;
+ parse->ppsparams.clear_offset.tv_nsec = -1e9*(parse->ppsphaseadjust - (long)parse->ppsphaseadjust);
+ }
+
+ if (mode1 == PPS_OFFSETASSERT)
+ {
+ parse->ppsparams.assert_offset.tv_sec = -parse->ppsphaseadjust;
+ parse->ppsparams.assert_offset.tv_nsec = -1e9*(parse->ppsphaseadjust - (long)parse->ppsphaseadjust);
+ }
+ }
+
+ /* only set what is legal */
+
+ parse->ppsparams.mode = (mode | mode1 | PPS_TSFMT_TSPEC) & cap;
+
+ if (time_pps_setparams(parse->ppshandle, &parse->ppsparams) < 0) {
+ msyslog(LOG_ERR, "PARSE receiver #%d: FAILED set PPS parameters: %m",
+ CLK_UNIT(parse->peer));
+ return 0;
+ }
+
+ parse->flags |= PARSE_PPSCLOCK;
+ return 1;
+}
+#else
+#define parse_hardpps(_PARSE_, _MODE_) /* empty */
+#endif
+
/*--------------------------------------------------
* parse_start - open the PARSE devices and initialize data for processing
*/
@@ -2465,9 +2807,20 @@ parse_start(
#endif
struct parseunit * parse;
char parsedev[sizeof(PARSEDEVICE)+20];
+ char parseppsdev[sizeof(PARSEPPSDEVICE)+20];
parsectl_t tmp_ctl;
u_int type;
+ /*
+ * get out Copyright information once
+ */
+ if (!notice)
+ {
+ NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
+ msyslog(LOG_INFO, "NTP PARSE support: Copyright (c) 1989-2006, Frank Kardel");
+ notice = 1;
+ }
+
type = CLK_TYPE(peer);
unit = CLK_UNIT(peer);
@@ -2481,7 +2834,8 @@ parse_start(
/*
* Unit okay, attempt to open the device.
*/
- (void) sprintf(parsedev, PARSEDEVICE, unit);
+ (void) snprintf(parsedev, sizeof(parsedev), PARSEDEVICE, unit);
+ (void) snprintf(parseppsdev, sizeof(parsedev), PARSEPPSDEVICE, unit);
#ifndef O_NOCTTY
#define O_NOCTTY 0
@@ -2512,15 +2866,14 @@ parse_start(
parse->generic->timestarted = current_time;
parse->lastchange = current_time;
- parse->generic->currentstatus = CEVNT_TIMEOUT; /* expect the worst */
-
parse->flags = 0;
parse->pollneeddata = 0;
parse->laststatistic = current_time;
parse->lastformat = (unsigned short)~0; /* assume no format known */
- parse->time.parse_status = (unsigned short)~0; /* be sure to mark initial status change */
+ parse->timedata.parse_status = (unsigned short)~0; /* be sure to mark initial status change */
parse->lastmissed = 0; /* assume got everything */
parse->ppsserial = 0;
+ parse->ppsfd = -1;
parse->localdata = (void *)0;
parse->localstate = 0;
parse->kv = (struct ctl_var *)0;
@@ -2529,17 +2882,21 @@ parse_start(
parse->parse_type = &parse_clockinfo[type];
+ parse->maxunsync = parse->parse_type->cl_maxunsync;
+
parse->generic->fudgetime1 = parse->parse_type->cl_basedelay;
parse->generic->fudgetime2 = 0.0;
+ parse->ppsphaseadjust = parse->generic->fudgetime2;
- parse->generic->clockdesc = parse->parse_type->cl_description;
+ parse->generic->clockdesc = parse->parse_type->cl_description;
peer->rootdelay = parse->parse_type->cl_rootdelay;
peer->sstclktype = parse->parse_type->cl_type;
peer->precision = sys_precision;
peer->stratum = STRATUM_REFCLOCK;
+
if (peer->stratum <= 1)
memmove((char *)&parse->generic->refid, parse->parse_type->cl_id, 4);
else
@@ -2607,38 +2964,84 @@ parse_start(
tio.c_cflag |= parse_clockinfo[type].cl_speed;
#endif
+ /*
+ * set up pps device
+ * if the PARSEPPSDEVICE can be opened that will be used
+ * for PPS else PARSEDEVICE will be used
+ */
+ parse->ppsfd = open(parseppsdev, O_RDWR | O_NOCTTY
+#ifdef O_NONBLOCK
+ | O_NONBLOCK
+#endif
+ , 0777);
+
+ if (parse->ppsfd == -1)
+ {
+ parse->ppsfd = fd232;
+ }
+
+/*
+ * Linux PPS - the old way
+ */
#if defined(HAVE_TIO_SERIAL_STUFF) /* Linux hack: define PPS interface */
{
- struct serial_struct ss;
- if (ioctl(fd232, TIOCGSERIAL, &ss) < 0 ||
- (
+ struct serial_struct ss;
+ if (ioctl(parse->ppsfd, TIOCGSERIAL, &ss) < 0 ||
+ (
#ifdef ASYNC_LOW_LATENCY
- ss.flags |= ASYNC_LOW_LATENCY,
+ ss.flags |= ASYNC_LOW_LATENCY,
+#endif
+#ifndef HAVE_PPSAPI
+#ifdef ASYNC_PPS_CD_NEG
+ ss.flags |= ASYNC_PPS_CD_NEG,
#endif
+#endif
+ ioctl(parse->ppsfd, TIOCSSERIAL, &ss)) < 0) {
+ msyslog(LOG_NOTICE, "refclock_parse: TIOCSSERIAL fd %d, %m", parse->ppsfd);
+ msyslog(LOG_NOTICE,
+ "refclock_parse: optional PPS processing not available");
+ } else {
+ parse->flags |= PARSE_PPSCLOCK;
#ifdef ASYNC_PPS_CD_NEG
- ss.flags |= ASYNC_PPS_CD_NEG,
+ NLOG(NLOG_CLOCKINFO)
+ msyslog(LOG_INFO,
+ "refclock_parse: PPS detection on");
#endif
- ioctl(fd232, TIOCSSERIAL, &ss)) < 0) {
- msyslog(LOG_NOTICE, "refclock_parse: TIOCSSERIAL fd %d, %m", fd232);
- msyslog(LOG_NOTICE,
- "refclock_parse: optional PPS processing not available");
- } else {
- parse->flags |= PARSE_PPSCLOCK;
- msyslog(LOG_INFO,
- "refclock_parse: PPS detection on");
- }
+ }
}
#endif
+
+/*
+ * SUN the Solaris way
+ */
#ifdef HAVE_TIOCSPPS /* SUN PPS support */
if (CLK_PPS(parse->peer))
- {
- int i = 1;
+ {
+ int i = 1;
- if (ioctl(fd232, TIOCSPPS, (caddr_t)&i) == 0)
- {
- parse->flags |= PARSE_PPSCLOCK;
- }
- }
+ if (ioctl(parse->ppsfd, TIOCSPPS, (caddr_t)&i) == 0)
+ {
+ parse->flags |= PARSE_PPSCLOCK;
+ }
+ }
+#endif
+
+/*
+ * PPS via PPSAPI
+ */
+#if defined(HAVE_PPSAPI)
+ parse->hardppsstate = PARSE_HARDPPS_DISABLE;
+ if (CLK_PPS(parse->peer))
+ {
+ if (time_pps_create(parse->ppsfd, &parse->ppshandle) < 0)
+ {
+ msyslog(LOG_NOTICE, "PARSE receiver #%d: parse_start: could not set up PPS: %m", CLK_UNIT(parse->peer));
+ }
+ else
+ {
+ parse_ppsapi(parse);
+ }
+ }
#endif
if (TTY_SETATTR(fd232, &tio) == -1)
@@ -2650,22 +3053,12 @@ parse_start(
}
/*
- * Insert in async io device list.
+ * pick correct input machine
*/
parse->generic->io.srcclock = (caddr_t)parse;
parse->generic->io.datalen = 0;
- if (!io_addclock(&parse->generic->io))
- {
- msyslog(LOG_ERR,
- "PARSE receiver #%d: parse_start: addclock %s fails (ABORT - clock type requires async io)", CLK_UNIT(parse->peer), parsedev);
- parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
- return 0;
- }
-
parse->binding = init_iobinding(parse);
- parse->generic->io.clock_recv = parse->binding->bd_receive; /* pick correct receive routine */
- parse->generic->io.io_input = parse->binding->bd_io_input; /* pick correct input routine */
if (parse->binding == (bind_t *)0)
{
@@ -2674,6 +3067,9 @@ parse_start(
return 0; /* well, ok - special initialisation broke */
}
+ parse->generic->io.clock_recv = parse->binding->bd_receive; /* pick correct receive routine */
+ parse->generic->io.io_input = parse->binding->bd_io_input; /* pick correct input routine */
+
/*
* as we always(?) get 8 bit chars we want to be
* sure, that the upper bits are zero for less
@@ -2708,7 +3104,7 @@ parse_start(
return 0; /* well, ok - special initialisation broke */
}
- strcpy(tmp_ctl.parseformat.parse_buffer, parse->parse_type->cl_format);
+ strncpy(tmp_ctl.parseformat.parse_buffer, parse->parse_type->cl_format, sizeof(tmp_ctl.parseformat.parse_buffer));
tmp_ctl.parseformat.parse_count = strlen(tmp_ctl.parseformat.parse_buffer);
if (!PARSE_SETFMT(parse, &tmp_ctl))
@@ -2724,11 +3120,8 @@ parse_start(
#ifdef HAVE_TERMIOS
(void) tcflush(parse->generic->io.fd, TCIOFLUSH);
#else
-#ifdef TCFLSH
+#if defined(TCFLSH) && defined(TCIOFLUSH)
{
-#ifndef TCIOFLUSH
-#define TCIOFLUSH 2
-#endif
int flshcmd = TCIOFLUSH;
(void) ioctl(parse->generic->io.fd, TCFLSH, (caddr_t)&flshcmd);
@@ -2749,13 +3142,14 @@ parse_start(
}
/*
- * get out Copyright information once
+ * Insert in async io device list.
*/
- if (!notice)
+ if (!io_addclock(&parse->generic->io))
{
- NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
- msyslog(LOG_INFO, "NTP PARSE support: Copyright (c) 1989-1999, Frank Kardel");
- notice = 1;
+ msyslog(LOG_ERR,
+ "PARSE receiver #%d: parse_start: addclock %s fails (ABORT - clock type requires async io)", CLK_UNIT(parse->peer), parsedev);
+ parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
+ return 0;
}
/*
@@ -2764,33 +3158,99 @@ parse_start(
NLOG(NLOG_CLOCKINFO)
{
/* conditional if clause for conditional syslog */
- msyslog(LOG_INFO, "PARSE receiver #%d: reference clock \"%s\" (device %s) added",
+ msyslog(LOG_INFO, "PARSE receiver #%d: reference clock \"%s\" (I/O device %s, PPS device %s) added",
CLK_UNIT(parse->peer),
- parse->parse_type->cl_description, parsedev);
+ parse->parse_type->cl_description, parsedev,
+ (parse->ppsfd != parse->generic->io.fd) ? parseppsdev : parsedev);
- msyslog(LOG_INFO, "PARSE receiver #%d: Stratum %d, %sPPS support, trust time %s, precision %d",
+ msyslog(LOG_INFO, "PARSE receiver #%d: Stratum %d, trust time %s, precision %d",
CLK_UNIT(parse->peer),
- parse->peer->stratum, CLK_PPS(parse->peer) ? "" : "no ",
- l_mktime(parse->parse_type->cl_maxunsync), parse->peer->precision);
+ parse->peer->stratum,
+ l_mktime(parse->maxunsync), parse->peer->precision);
- msyslog(LOG_INFO, "PARSE receiver #%d: rootdelay %.6f s, phaseadjust %.6f s, %s IO handling",
+ msyslog(LOG_INFO, "PARSE receiver #%d: rootdelay %.6f s, phase adjustment %.6f s, PPS phase adjustment %.6f s, %s IO handling",
CLK_UNIT(parse->peer),
parse->parse_type->cl_rootdelay,
parse->generic->fudgetime1,
- parse->binding->bd_description);
+ parse->ppsphaseadjust,
+ parse->binding->bd_description);
- msyslog(LOG_INFO, "PARSE receiver #%d: Format recognition: %s", CLK_UNIT(parse->peer),
+ msyslog(LOG_INFO, "PARSE receiver #%d: Format recognition: %s", CLK_UNIT(parse->peer),
parse->parse_type->cl_format);
-#ifdef PPS
- msyslog(LOG_INFO, "PARSE receiver #%d: %sPPS ioctl support", CLK_UNIT(parse->peer),
- (parse->flags & PARSE_PPSCLOCK) ? "" : "NO ");
+ msyslog(LOG_INFO, "PARSE receiver #%d: %sPPS support%s", CLK_UNIT(parse->peer),
+ CLK_PPS(parse->peer) ? "" : "NO ",
+ CLK_PPS(parse->peer) ?
+#ifdef PPS_METHOD
+ " (implementation " PPS_METHOD ")"
+#else
+ ""
#endif
+ : ""
+ );
}
return 1;
}
/*--------------------------------------------------
+ * parse_ctl - process changes on flags/time values
+ */
+static void
+parse_ctl(
+ struct parseunit *parse,
+ struct refclockstat *in
+ )
+{
+ if (in)
+ {
+ if (in->haveflags & (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4))
+ {
+ parse->flags = (parse->flags & ~(CLK_FLAG1|CLK_FLAG2|CLK_FLAG3|CLK_FLAG4)) |
+ (in->flags & (CLK_FLAG1|CLK_FLAG2|CLK_FLAG3|CLK_FLAG4));
+#if defined(HAVE_PPSAPI)
+ if (CLK_PPS(parse->peer))
+ {
+ parse_ppsapi(parse);
+ }
+#endif
+ }
+
+ if (in->haveflags & CLK_HAVETIME1)
+ {
+ parse->generic->fudgetime1 = in->fudgetime1;
+ msyslog(LOG_INFO, "PARSE receiver #%d: new phase adjustment %.6f s",
+ CLK_UNIT(parse->peer),
+ parse->generic->fudgetime1);
+ }
+
+ if (in->haveflags & CLK_HAVETIME2)
+ {
+ parse->generic->fudgetime2 = in->fudgetime2;
+ if (parse->flags & PARSE_TRUSTTIME)
+ {
+ parse->maxunsync = (u_long)ABS(in->fudgetime2);
+ msyslog(LOG_INFO, "PARSE receiver #%d: new trust time %s",
+ CLK_UNIT(parse->peer),
+ l_mktime(parse->maxunsync));
+ }
+ else
+ {
+ parse->ppsphaseadjust = in->fudgetime2;
+ msyslog(LOG_INFO, "PARSE receiver #%d: new PPS phase adjustment %.6f s",
+ CLK_UNIT(parse->peer),
+ parse->ppsphaseadjust);
+#if defined(HAVE_PPSAPI)
+ if (CLK_PPS(parse->peer))
+ {
+ parse_ppsapi(parse);
+ }
+#endif
+ }
+ }
+ }
+}
+
+/*--------------------------------------------------
* parse_poll - called by the transmit procedure
*/
static void
@@ -2821,12 +3281,11 @@ parse_poll(
* start worrying when exceeding a poll inteval
* bad news - didn't get a response last time
*/
- parse->generic->noreply++;
parse->lastmissed = current_time;
parse_event(parse, CEVNT_TIMEOUT);
ERR(ERR_NODATA)
- msyslog(LOG_WARNING, "PARSE receiver #%d: no data from device within poll interval (check receiver / cableling)", CLK_UNIT(parse->peer));
+ msyslog(LOG_WARNING, "PARSE receiver #%d: no data from device within poll interval (check receiver / wiring)", CLK_UNIT(parse->peer));
}
/*
@@ -2857,7 +3316,7 @@ parse_control(
struct peer *peer
)
{
- register struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr;
+ struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr;
parsectl_t tmpctl;
static char outstatus[400]; /* status output buffer */
@@ -2878,32 +3337,36 @@ parse_control(
unit = CLK_UNIT(parse->peer);
- if (in)
- {
- if (in->haveflags & (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4))
- {
- parse->flags = in->flags & (CLK_FLAG1|CLK_FLAG2|CLK_FLAG3|CLK_FLAG4);
- }
- }
-
+ /*
+ * handle changes
+ */
+ parse_ctl(parse, in);
+
+ /*
+ * supply data
+ */
if (out)
{
u_long sum = 0;
- char *t, *tt, *start;
+ char *tt, *start;
int i;
outstatus[0] = '\0';
out->type = REFCLK_PARSE;
- out->haveflags |= CLK_HAVETIME2;
+
+ /*
+ * keep fudgetime2 in sync with TRUSTTIME/MAXUNSYNC flag1
+ */
+ parse->generic->fudgetime2 = (parse->flags & PARSE_TRUSTTIME) ? (double)parse->maxunsync : parse->ppsphaseadjust;
/*
* figure out skew between PPS and RS232 - just for informational
- * purposes - returned in time2 value
+ * purposes
*/
- if (PARSE_SYNC(parse->time.parse_state))
+ if (PARSE_SYNC(parse->timedata.parse_state))
{
- if (PARSE_PPS(parse->time.parse_state) && PARSE_TIMECODE(parse->time.parse_state))
+ if (PARSE_PPS(parse->timedata.parse_state) && PARSE_TIMECODE(parse->timedata.parse_state))
{
l_fp off;
@@ -2911,31 +3374,30 @@ parse_control(
* we have a PPS and RS232 signal - calculate the skew
* WARNING: assumes on TIMECODE == PULSE (timecode after pulse)
*/
- off = parse->time.parse_stime.fp;
- L_SUB(&off, &parse->time.parse_ptime.fp); /* true offset */
+ off = parse->timedata.parse_stime.fp;
+ L_SUB(&off, &parse->timedata.parse_ptime.fp); /* true offset */
tt = add_var(&out->kv_list, 80, RO);
- sprintf(tt, "refclock_ppsskew=%s", lfptoms(&off, 6));
+ snprintf(tt, 80, "refclock_ppsskew=%s", lfptoms(&off, 6));
}
}
- if (PARSE_PPS(parse->time.parse_state))
+ if (PARSE_PPS(parse->timedata.parse_state))
{
tt = add_var(&out->kv_list, 80, RO|DEF);
- sprintf(tt, "refclock_ppstime=\"%s\"", gmprettydate(&parse->time.parse_ptime.fp));
+ snprintf(tt, 80, "refclock_ppstime=\"%s\"", gmprettydate(&parse->timedata.parse_ptime.fp));
}
- tt = add_var(&out->kv_list, 128, RO|DEF);
- sprintf(tt, "refclock_time=\"");
+ start = tt = add_var(&out->kv_list, 128, RO|DEF);
+ snprintf(tt, 128, "refclock_time=\"");
tt += strlen(tt);
- if (parse->time.parse_time.fp.l_ui == 0)
+ if (parse->timedata.parse_time.fp.l_ui == 0)
{
- strcpy(tt, "<UNDEFINED>\"");
+ strncpy(tt, "<UNDEFINED>\"", BUFFER_SIZES(start, tt, 128));
}
else
{
- sprintf(tt, "%s\"", gmprettydate(&parse->time.parse_time.fp));
- t = tt + strlen(tt);
+ snprintf(tt, 128, "%s\"", gmprettydate(&parse->timedata.parse_time.fp));
}
if (!PARSE_GETTIMECODE(parse, &tmpctl))
@@ -2945,25 +3407,24 @@ parse_control(
}
else
{
- tt = add_var(&out->kv_list, 512, RO|DEF);
- sprintf(tt, "refclock_status=\"");
+ start = tt = add_var(&out->kv_list, 512, RO|DEF);
+ snprintf(tt, 512, "refclock_status=\"");
tt += strlen(tt);
/*
* copy PPS flags from last read transaction (informational only)
*/
- tmpctl.parsegettc.parse_state |= parse->time.parse_state &
+ tmpctl.parsegettc.parse_state |= parse->timedata.parse_state &
(PARSEB_PPS|PARSEB_S_PPS);
- (void) parsestate(tmpctl.parsegettc.parse_state, tt);
+ (void) parsestate(tmpctl.parsegettc.parse_state, tt, BUFFER_SIZES(start, tt, 512));
- strcat(tt, "\"");
+ strncat(tt, "\"", BUFFER_SIZES(start, tt, 512));
if (tmpctl.parsegettc.parse_count)
mkascii(outstatus+strlen(outstatus), (int)(sizeof(outstatus)- strlen(outstatus) - 1),
- tmpctl.parsegettc.parse_buffer, (unsigned)(tmpctl.parsegettc.parse_count - 1));
+ tmpctl.parsegettc.parse_buffer, (unsigned)(tmpctl.parsegettc.parse_count));
- parse->generic->badformat += tmpctl.parsegettc.parse_badformat;
}
tmpctl.parseformat.parse_format = tmpctl.parsegettc.parse_format;
@@ -2976,10 +3437,10 @@ parse_control(
else
{
tt = add_var(&out->kv_list, 80, RO|DEF);
- sprintf(tt, "refclock_format=\"");
+ snprintf(tt, 80, "refclock_format=\"");
strncat(tt, tmpctl.parseformat.parse_buffer, tmpctl.parseformat.parse_count);
- strcat(tt,"\"");
+ strncat(tt,"\"", 80);
}
/*
@@ -2987,7 +3448,7 @@ parse_control(
*/
start = tt = add_var(&out->kv_list, LEN_STATES, RO|DEF);
- strcpy(tt, "refclock_states=\"");
+ strncpy(tt, "refclock_states=\"", LEN_STATES);
tt += strlen(tt);
for (i = 0; i <= CEVNT_MAX; i++)
@@ -3014,7 +3475,7 @@ parse_control(
char item[80];
int count;
- sprintf(item, "%s%s%s: %s (%d.%02d%%)",
+ snprintf(item, 80, "%s%s%s: %s (%d.%02d%%)",
sum ? "; " : "",
(parse->generic->currentstatus == i) ? "*" : "",
clockstatus((unsigned int)i),
@@ -3022,23 +3483,23 @@ parse_control(
(int)(percent / 100), (int)(percent % 100));
if ((count = strlen(item)) < (LEN_STATES - 40 - (tt - start)))
{
- strcpy(tt, item);
+ strncpy(tt, item, BUFFER_SIZES(start, tt, LEN_STATES));
tt += count;
}
sum += s_time;
}
}
- sprintf(tt, "; running time: %s\"", l_mktime(sum));
+ snprintf(tt, BUFFER_SIZES(start, tt, LEN_STATES), "; running time: %s\"", l_mktime(sum));
tt = add_var(&out->kv_list, 32, RO);
- sprintf(tt, "refclock_id=\"%s\"", parse->parse_type->cl_id);
+ snprintf(tt, 32, "refclock_id=\"%s\"", parse->parse_type->cl_id);
tt = add_var(&out->kv_list, 80, RO);
- sprintf(tt, "refclock_iomode=\"%s\"", parse->binding->bd_description);
+ snprintf(tt, 80, "refclock_iomode=\"%s\"", parse->binding->bd_description);
tt = add_var(&out->kv_list, 128, RO);
- sprintf(tt, "refclock_driver_version=\"%s\"", rcsid);
+ snprintf(tt, 128, "refclock_driver_version=\"%s\"", rcsid);
{
struct ctl_var *k;
@@ -3062,6 +3523,7 @@ parse_control(
/*--------------------------------------------------
* event handling - note that nominal events will also be posted
+ * keep track of state dwelling times
*/
static void
parse_event(
@@ -3074,41 +3536,17 @@ parse_event(
parse->statetime[parse->generic->currentstatus] += current_time - parse->lastchange;
parse->lastchange = current_time;
- parse->generic->currentstatus = (u_char)event;
-
if (parse->parse_type->cl_event)
parse->parse_type->cl_event(parse, event);
- if (event != CEVNT_NOMINAL)
- {
- parse->generic->lastevent = parse->generic->currentstatus;
- }
- else
+ if (event == CEVNT_NOMINAL)
{
NLOG(NLOG_CLOCKSTATUS)
msyslog(LOG_INFO, "PARSE receiver #%d: SYNCHRONIZED",
CLK_UNIT(parse->peer));
}
- if (event == CEVNT_FAULT)
- {
- NLOG(NLOG_CLOCKEVENT) /* conditional if clause for conditional syslog */
- ERR(ERR_BADEVENT)
- msyslog(LOG_ERR,
- "clock %s fault '%s' (0x%02x)", refnumtoa(&parse->peer->srcadr), ceventstr(event),
- (u_int)event);
- }
- else
- {
- NLOG(NLOG_CLOCKEVENT) /* conditional if clause for conditional syslog */
- if (event == CEVNT_NOMINAL || list_err(parse, ERR_BADEVENT))
- msyslog(LOG_INFO,
- "clock %s event '%s' (0x%02x)", refnumtoa(&parse->peer->srcadr), ceventstr(event),
- (u_int)event);
- }
-
- report_event(EVNT_PEERCLOCK, parse->peer);
- report_event(EVNT_CLOCKEXCPT, parse->peer);
+ refclock_report(parse->peer, event);
}
}
@@ -3130,13 +3568,13 @@ parse_process(
*/
if (((parsetime->parse_status & CVT_MASK) != CVT_OK) &&
((parsetime->parse_status & CVT_MASK) != CVT_NONE) &&
- (parse->time.parse_status != parsetime->parse_status))
+ (parse->timedata.parse_status != parsetime->parse_status))
{
char buffer[400];
NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
msyslog(LOG_WARNING, "PARSE receiver #%d: conversion status \"%s\"",
- CLK_UNIT(parse->peer), parsestatus(parsetime->parse_status, buffer));
+ CLK_UNIT(parse->peer), parsestatus(parsetime->parse_status, buffer, sizeof(buffer)));
if ((parsetime->parse_status & CVT_MASK) == CVT_FAIL)
{
@@ -3155,9 +3593,8 @@ parse_process(
else
{
ERR(ERR_BADDATA)
- msyslog(LOG_WARNING, "PARSE receiver #%d: FAILED TIMECODE: \"%s\" (check receiver configuration / cableling)",
+ msyslog(LOG_WARNING, "PARSE receiver #%d: FAILED TIMECODE: \"%s\" (check receiver configuration / wiring)",
CLK_UNIT(parse->peer), mkascii(buffer, sizeof buffer, tmpctl.parsegettc.parse_buffer, (unsigned)(tmpctl.parsegettc.parse_count - 1)));
- parse->generic->badformat += tmpctl.parsegettc.parse_badformat;
}
}
}
@@ -3176,10 +3613,17 @@ parse_process(
if ((parsetime->parse_status & CVT_ADDITIONAL) &&
parse->parse_type->cl_message)
parse->parse_type->cl_message(parse, parsetime);
+ /*
+ * save PPS information that comes piggyback
+ */
+ if (PARSE_PPS(parsetime->parse_state))
+ {
+ parse->timedata.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
+ parse->timedata.parse_ptime = parsetime->parse_ptime;
+ }
break; /* well, still waiting - timeout is handled at higher levels */
case CVT_FAIL:
- parse->generic->badformat++;
if (parsetime->parse_status & CVT_BADFMT)
{
parse_event(parse, CEVNT_BADREPLY);
@@ -3229,16 +3673,17 @@ parse_process(
/*
* now, any changes ?
*/
- if (parse->time.parse_state != parsetime->parse_state)
+ if ((parse->timedata.parse_state ^ parsetime->parse_state) &
+ ~(unsigned)(PARSEB_PPS|PARSEB_S_PPS))
{
char tmp1[200];
char tmp2[200];
/*
- * something happend
+ * something happend - except for PPS events
*/
- (void) parsestate(parsetime->parse_state, tmp1);
- (void) parsestate(parse->time.parse_state, tmp2);
+ (void) parsestate(parsetime->parse_state, tmp1, sizeof(tmp1));
+ (void) parsestate(parse->timedata.parse_state, tmp2, sizeof(tmp2));
NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
msyslog(LOG_INFO,"PARSE receiver #%d: STATE CHANGE: %s -> %s",
@@ -3246,9 +3691,18 @@ parse_process(
}
/*
+ * carry on PPS information if still usable
+ */
+ if (PARSE_PPS(parse->timedata.parse_state) && !PARSE_PPS(parsetime->parse_state))
+ {
+ parsetime->parse_state |= PARSEB_PPS|PARSEB_S_PPS;
+ parsetime->parse_ptime = parse->timedata.parse_ptime;
+ }
+
+ /*
* remember for future
*/
- parse->time = *parsetime;
+ parse->timedata = *parsetime;
/*
* check to see, whether the clock did a complete powerup or lost PZF signal
@@ -3351,6 +3805,17 @@ parse_process(
if (PARSE_PPS(parsetime->parse_state) && CLK_PPS(parse->peer))
{
l_fp offset;
+ double ppsphaseadjust = parse->ppsphaseadjust;
+
+#ifdef HAVE_PPSAPI
+ /*
+ * set fudge = 0.0 if already included in PPS time stamps
+ */
+ if (parse->ppsparams.mode & (PPS_OFFSETCLEAR|PPS_OFFSETASSERT))
+ {
+ ppsphaseadjust = 0.0;
+ }
+#endif
/*
* we have a PPS signal - much better than the RS232 stuff (we hope)
@@ -3368,7 +3833,7 @@ parse_process(
if (M_ISGEQ(off.l_i, off.l_f, -1, 0x80000000) &&
M_ISGEQ(0, 0x7fffffff, off.l_i, off.l_f))
{
- fudge = parse->generic->fudgetime2; /* pick PPS fudge factor */
+ fudge = ppsphaseadjust; /* pick PPS fudge factor */
/*
* RS232 offsets within [-0.5..0.5[ - take PPS offsets
@@ -3404,7 +3869,7 @@ parse_process(
}
else
{
- fudge = parse->generic->fudgetime2; /* pick PPS fudge factor */
+ fudge = ppsphaseadjust; /* pick PPS fudge factor */
/*
* Well, no time code to guide us - assume on second pulse
* and pray, that we are within [-0.5..0.5[
@@ -3473,35 +3938,22 @@ parse_process(
clear_err(parse, ERR_NODATA);
clear_err(parse, ERR_INTERNAL);
-#ifdef DEBUG
- if (debug > 2)
- {
- printf("PARSE receiver #%d: refclock_process_offset(reftime=%s, rectime=%s, Fudge=%f)\n",
- CLK_UNIT(parse->peer),
- prettydate(&reftime),
- prettydate(&rectime),
- fudge);
- }
-#endif
-
- refclock_process_offset(parse->generic, reftime, rectime, fudge);
- if (PARSE_PPS(parsetime->parse_state) && CLK_PPS(parse->peer))
- {
- (void) pps_sample(&parse->time.parse_ptime.fp);
- }
-
-
/*
* and now stick it into the clock machine
* samples are only valid iff lastsync is not too old and
* we have seen the clock in sync at least once
* after the last time we didn't see an expected data telegram
+ * at startup being not in sync is also bad just like
+ * POWERUP state
* see the clock states section above for more reasoning
*/
- if (((current_time - parse->lastsync) > parse->parse_type->cl_maxunsync) ||
- (parse->lastsync <= parse->lastmissed))
+ if (((current_time - parse->lastsync) > parse->maxunsync) ||
+ (parse->lastsync < parse->lastmissed) ||
+ ((parse->lastsync == 0) && !PARSE_SYNC(parsetime->parse_state)) ||
+ PARSE_POWERUP(parsetime->parse_state))
{
parse->generic->leap = LEAP_NOTINSYNC;
+ parse->lastsync = 0; /* wait for full sync again */
}
else
{
@@ -3524,15 +3976,49 @@ parse_process(
parse->generic->leap = LEAP_NOWARNING;
}
}
-
+
+ if (parse->generic->leap != LEAP_NOTINSYNC)
+ {
+ /*
+ * only good/trusted samples are interesting
+ */
+#ifdef DEBUG
+ if (debug > 2)
+ {
+ printf("PARSE receiver #%d: refclock_process_offset(reftime=%s, rectime=%s, Fudge=%f)\n",
+ CLK_UNIT(parse->peer),
+ prettydate(&reftime),
+ prettydate(&rectime),
+ fudge);
+ }
+#endif
+ parse->generic->lastref = reftime;
+
+ refclock_process_offset(parse->generic, reftime, rectime, fudge);
+
+ /*
+ * pass PPS information on to PPS clock
+ */
+ if (PARSE_PPS(parsetime->parse_state) && CLK_PPS(parse->peer))
+ {
+ (void) pps_sample(&parse->timedata.parse_ptime.fp);
+ parse_hardpps(parse, PARSE_HARDPPS_ENABLE);
+ }
+ } else {
+ parse_hardpps(parse, PARSE_HARDPPS_DISABLE);
+ }
+
/*
- * ready, unless the machine wants a sample
+ * ready, unless the machine wants a sample or
+ * we are in fast startup mode (peer->dist > MAXDISTANCE)
*/
- if (!parse->pollneeddata)
+ if (!parse->pollneeddata && parse->peer->disp <= MAXDISTANCE)
return;
parse->pollneeddata = 0;
+ parse->timedata.parse_state &= ~(unsigned)(PARSEB_PPS|PARSEB_S_PPS);
+
refclock_receive(parse->peer);
}
@@ -3547,12 +4033,14 @@ mk_utcinfo(
int wnlsf,
int dn,
int dtls,
- int dtlsf
+ int dtlsf,
+ int size
)
{
l_fp leapdate;
+ char *start = t;
- sprintf(t, "current correction %d sec", dtls);
+ snprintf(t, size, "current correction %d sec", dtls);
t += strlen(t);
if (wnlsf < 990)
@@ -3566,12 +4054,12 @@ mk_utcinfo(
if ((dtlsf != dtls) &&
((wnlsf - wnt) < 52))
{
- sprintf(t, ", next correction %d sec on %s, new GPS-UTC offset %d",
+ snprintf(t, BUFFER_SIZES(start, t, size), ", next correction %d sec on %s, new GPS-UTC offset %d",
dtlsf - dtls, gmprettydate(&leapdate), dtlsf);
}
else
{
- sprintf(t, ", last correction on %s",
+ snprintf(t, BUFFER_SIZES(start, t, size), ", last correction on %s",
gmprettydate(&leapdate));
}
}
@@ -3590,7 +4078,7 @@ gps16x_message(
parsetime_t *parsetime
)
{
- if (parse->time.parse_msglen && parsetime->parse_msg[0] == SOH)
+ if (parse->timedata.parse_msglen && parsetime->parse_msg[0] == SOH)
{
GPS_MSG_HDR header;
unsigned char *bufp = (unsigned char *)parsetime->parse_msg + 1;
@@ -3624,12 +4112,12 @@ gps16x_message(
SW_REV gps_sw_rev;
get_mbg_sw_rev(&bufp, &gps_sw_rev);
- sprintf(buffer, "meinberg_gps_version=\"%x.%02x%s%s\"",
+ snprintf(buffer, sizeof(buffer), "meinberg_gps_version=\"%x.%02x%s%s\"",
(gps_sw_rev.code >> 8) & 0xFF,
gps_sw_rev.code & 0xFF,
gps_sw_rev.name[0] ? " " : "",
gps_sw_rev.name);
- set_var(&parse->kv, buffer, 64, RO|DEF);
+ set_var(&parse->kv, buffer, strlen(buffer)+1, RO|DEF);
}
break;
@@ -3653,7 +4141,7 @@ gps16x_message(
char *p, *b;
status = get_lsb_short(&bufp);
- sprintf(buffer, "meinberg_gps_status=\"[0x%04x] ", status);
+ snprintf(buffer, sizeof(buffer), "meinberg_gps_status=\"[0x%04x] ", status);
if (status)
{
@@ -3668,7 +4156,7 @@ gps16x_message(
*p++ = ' ';
}
- strcat(p, (const char *)s->string);
+ strncat(p, (const char *)s->string, sizeof(buffer));
}
s++;
}
@@ -3678,10 +4166,10 @@ gps16x_message(
}
else
{
- strcat(buffer, "<OK>\"");
+ strncat(buffer, "<OK>\"", sizeof(buffer));
}
- set_var(&parse->kv, buffer, 64, RO|DEF);
+ set_var(&parse->kv, buffer, strlen(buffer)+1, RO|DEF);
}
break;
@@ -3691,7 +4179,7 @@ gps16x_message(
char buffer[256];
get_mbg_xyz(&bufp, xyz);
- sprintf(buffer, "gps_position(XYZ)=\"%s m, %s m, %s m\"",
+ snprintf(buffer, sizeof(buffer), "gps_position(XYZ)=\"%s m, %s m, %s m\"",
mfptoa(xyz[XP].l_ui, xyz[XP].l_uf, 1),
mfptoa(xyz[YP].l_ui, xyz[YP].l_uf, 1),
mfptoa(xyz[ZP].l_ui, xyz[ZP].l_uf, 1));
@@ -3707,7 +4195,7 @@ gps16x_message(
get_mbg_lla(&bufp, lla);
- sprintf(buffer, "gps_position(LLA)=\"%s deg, %s deg, %s m\"",
+ snprintf(buffer, sizeof(buffer), "gps_position(LLA)=\"%s deg, %s deg, %s m\"",
mfptoa(lla[LAT].l_ui, lla[LAT].l_uf, 4),
mfptoa(lla[LON].l_ui, lla[LON].l_uf, 4),
mfptoa(lla[ALT].l_ui, lla[ALT].l_uf, 1));
@@ -3728,55 +4216,54 @@ gps16x_message(
case GPS_ANT_INFO:
{
ANT_INFO antinfo;
- u_char buffer[512];
- u_char *p;
+ char buffer[512];
+ char *p;
get_mbg_antinfo(&bufp, &antinfo);
- sprintf(buffer, "meinberg_antenna_status=\"");
+ snprintf(buffer, sizeof(buffer), "meinberg_antenna_status=\"");
p = buffer + strlen(buffer);
switch (antinfo.status)
{
case ANT_INVALID:
- strcat(p, "<OK>");
+ strncat(p, "<OK>", BUFFER_SIZE(buffer, p));
p += strlen(p);
break;
case ANT_DISCONN:
- strcat(p, "DISCONNECTED since ");
+ strncat(p, "DISCONNECTED since ", BUFFER_SIZE(buffer, p));
NLOG(NLOG_CLOCKSTATUS)
ERR(ERR_BADSTATUS)
msyslog(LOG_ERR,"PARSE receiver #%d: ANTENNA FAILURE: %s",
CLK_UNIT(parse->peer), p);
p += strlen(p);
- mbg_tm_str(&p, &antinfo.tm_disconn);
+ mbg_tm_str(&p, &antinfo.tm_disconn, BUFFER_SIZE(buffer, p));
*p = '\0';
break;
case ANT_RECONN:
- strcat(p, "RECONNECTED on ");
+ strncat(p, "RECONNECTED on ", BUFFER_SIZE(buffer, p));
p += strlen(p);
- mbg_tm_str(&p, &antinfo.tm_reconn);
- sprintf(p, ", reconnect clockoffset %c%ld.%07ld s, disconnect time ",
+ mbg_tm_str(&p, &antinfo.tm_reconn, BUFFER_SIZE(buffer, p));
+ snprintf(p, BUFFER_SIZE(buffer, p), ", reconnect clockoffset %c%ld.%07ld s, disconnect time ",
(antinfo.delta_t < 0) ? '-' : '+',
ABS(antinfo.delta_t) / 10000,
ABS(antinfo.delta_t) % 10000);
p += strlen(p);
- mbg_tm_str(&p, &antinfo.tm_disconn);
+ mbg_tm_str(&p, &antinfo.tm_disconn, BUFFER_SIZE(buffer, p));
*p = '\0';
break;
default:
- sprintf(p, "bad status 0x%04x", antinfo.status);
+ snprintf(p, BUFFER_SIZE(buffer, p), "bad status 0x%04x", antinfo.status);
p += strlen(p);
break;
}
- *p++ = '"';
- *p = '\0';
+ strncat(p, "\"", BUFFER_SIZE(buffer, p));
- set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF);
+ set_var(&parse->kv, buffer, strlen(buffer)+1, RO|DEF);
}
break;
@@ -3786,8 +4273,8 @@ gps16x_message(
case GPS_CFGH:
{
CFGH cfgh;
- u_char buffer[512];
- u_char *p;
+ char buffer[512];
+ char *p;
get_mbg_cfgh(&bufp, &cfgh);
if (cfgh.valid)
@@ -3795,77 +4282,74 @@ gps16x_message(
int i;
p = buffer;
- strcpy(buffer, "gps_tot_51=\"");
+ strncpy(buffer, "gps_tot_51=\"", BUFFER_SIZE(buffer, p));
p += strlen(p);
- mbg_tgps_str(&p, &cfgh.tot_51);
- *p++ = '"';
- *p = '\0';
- set_var(&parse->kv, buffer, sizeof(buffer), RO);
+ mbg_tgps_str(&p, &cfgh.tot_51, BUFFER_SIZE(buffer, p));
+ strncpy(p, "\"", BUFFER_SIZE(buffer, p));
+ set_var(&parse->kv, buffer, strlen(buffer)+1, RO);
p = buffer;
- strcpy(buffer, "gps_tot_63=\"");
+ strncpy(buffer, "gps_tot_63=\"", BUFFER_SIZE(buffer, p));
p += strlen(p);
- mbg_tgps_str(&p, &cfgh.tot_63);
- *p++ = '"';
- *p = '\0';
- set_var(&parse->kv, buffer, sizeof(buffer), RO);
+ mbg_tgps_str(&p, &cfgh.tot_63, BUFFER_SIZE(buffer, p));
+ strncpy(p, "\"", BUFFER_SIZE(buffer, p));
+ set_var(&parse->kv, buffer, strlen(buffer)+1, RO);
p = buffer;
- strcpy(buffer, "gps_t0a=\"");
+ strncpy(buffer, "gps_t0a=\"", BUFFER_SIZE(buffer, p));
p += strlen(p);
- mbg_tgps_str(&p, &cfgh.t0a);
- *p++ = '"';
- *p = '\0';
- set_var(&parse->kv, buffer, sizeof(buffer), RO);
+ mbg_tgps_str(&p, &cfgh.t0a, BUFFER_SIZE(buffer, p));
+ strncpy(p, "\"", BUFFER_SIZE(buffer, p));
+ set_var(&parse->kv, buffer, strlen(buffer)+1, RO);
- for (i = MIN_SVNO; i <= MAX_SVNO; i++)
+ for (i = MIN_SVNO; i < MAX_SVNO; i++)
{
p = buffer;
- sprintf(p, "gps_cfg[%d]=\"[0x%x] ", i, cfgh.cfg[i]);
+ snprintf(p, BUFFER_SIZE(buffer, p), "gps_cfg[%d]=\"[0x%x] ", i, cfgh.cfg[i]);
p += strlen(p);
switch (cfgh.cfg[i] & 0x7)
{
case 0:
- strcpy(p, "BLOCK I");
+ strncpy(p, "BLOCK I", BUFFER_SIZE(buffer, p));
break;
case 1:
- strcpy(p, "BLOCK II");
+ strncpy(p, "BLOCK II", BUFFER_SIZE(buffer, p));
break;
default:
- sprintf(p, "bad CFG");
+ strncpy(p, "bad CFG", BUFFER_SIZE(buffer, p));
break;
}
- strcat(p, "\"");
- set_var(&parse->kv, buffer, sizeof(buffer), RO);
+ strncat(p, "\"", BUFFER_SIZE(buffer, p));
+ set_var(&parse->kv, buffer, strlen(buffer)+1, RO);
p = buffer;
- sprintf(p, "gps_health[%d]=\"[0x%x] ", i, cfgh.health[i]);
+ snprintf(p, BUFFER_SIZE(buffer, p), "gps_health[%d]=\"[0x%x] ", i, cfgh.health[i]);
p += strlen(p);
switch ((cfgh.health[i] >> 5) & 0x7 )
{
case 0:
- strcpy(p, "OK;");
+ strncpy(p, "OK;", BUFFER_SIZE(buffer, p));
break;
case 1:
- strcpy(p, "PARITY;");
+ strncpy(p, "PARITY;", BUFFER_SIZE(buffer, p));
break;
case 2:
- strcpy(p, "TLM/HOW;");
+ strncpy(p, "TLM/HOW;", BUFFER_SIZE(buffer, p));
break;
case 3:
- strcpy(p, "Z-COUNT;");
+ strncpy(p, "Z-COUNT;", BUFFER_SIZE(buffer, p));
break;
case 4:
- strcpy(p, "SUBFRAME 1,2,3;");
+ strncpy(p, "SUBFRAME 1,2,3;", BUFFER_SIZE(buffer, p));
break;
case 5:
- strcpy(p, "SUBFRAME 4,5;");
+ strncpy(p, "SUBFRAME 4,5;", BUFFER_SIZE(buffer, p));
break;
case 6:
- strcpy(p, "UPLOAD BAD;");
+ strncpy(p, "UPLOAD BAD;", BUFFER_SIZE(buffer, p));
break;
case 7:
- strcpy(p, "DATA BAD;");
+ strncpy(p, "DATA BAD;", BUFFER_SIZE(buffer, p));
break;
}
@@ -3874,26 +4358,26 @@ gps16x_message(
switch (cfgh.health[i] & 0x1F)
{
case 0:
- strcpy(p, "SIGNAL OK");
+ strncpy(p, "SIGNAL OK", BUFFER_SIZE(buffer, p));
break;
case 0x1C:
- strcpy(p, "SV TEMP OUT");
+ strncpy(p, "SV TEMP OUT", BUFFER_SIZE(buffer, p));
break;
case 0x1D:
- strcpy(p, "SV WILL BE TEMP OUT");
+ strncpy(p, "SV WILL BE TEMP OUT", BUFFER_SIZE(buffer, p));
break;
case 0x1E:
break;
case 0x1F:
- strcpy(p, "MULTIPLE ERRS");
+ strncpy(p, "MULTIPLE ERRS", BUFFER_SIZE(buffer, p));
break;
default:
- strcpy(p, "TRANSMISSION PROBLEMS");
+ strncpy(p, "TRANSMISSION PROBLEMS", BUFFER_SIZE(buffer, p));
break;
}
- strcat(p, "\"");
- set_var(&parse->kv, buffer, sizeof(buffer), RO);
+ strncat(p, "\"", sizeof(buffer));
+ set_var(&parse->kv, buffer, strlen(buffer)+1, RO);
}
}
}
@@ -3917,16 +4401,16 @@ gps16x_message(
if (utc.valid)
{
- strcpy(p, "gps_utc_correction=\"");
+ strncpy(p, "gps_utc_correction=\"", sizeof(buffer));
p += strlen(p);
- mk_utcinfo(p, utc.t0t.wn, utc.WNlsf, utc.DNt, utc.delta_tls, utc.delta_tlsf);
- strcat(p, "\"");
+ mk_utcinfo(p, utc.t0t.wn, utc.WNlsf, utc.DNt, utc.delta_tls, utc.delta_tlsf, BUFFER_SIZE(buffer, p));
+ strncat(p, "\"", BUFFER_SIZE(buffer, p));
}
else
{
- strcpy(p, "gps_utc_correction=\"<NO UTC DATA>\"");
+ strncpy(p, "gps_utc_correction=\"<NO UTC DATA>\"", BUFFER_SIZE(buffer, p));
}
- set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF);
+ set_var(&parse->kv, buffer, strlen(buffer)+1, RO|DEF);
}
break;
@@ -3945,12 +4429,12 @@ gps16x_message(
char buffer1[128];
mkreadable(buffer1, sizeof(buffer1), gps_ascii_msg.s, strlen(gps_ascii_msg.s), (int)0);
- sprintf(buffer, "gps_message=\"%s\"", buffer1);
+ snprintf(buffer, sizeof(buffer), "gps_message=\"%s\"", buffer1);
}
else
- strcpy(buffer, "gps_message=<NONE>");
+ strncpy(buffer, "gps_message=<NONE>", sizeof(buffer));
- set_var(&parse->kv, buffer, 128, RO|DEF);
+ set_var(&parse->kv, buffer, strlen(buffer)+1, RO|DEF);
}
break;
@@ -4331,6 +4815,7 @@ trimbletaip_event(
typedef struct trimble
{
u_long last_msg; /* last message received */
+ u_long last_reset; /* last time a reset was issued */
u_char qtracking; /* query tracking status */
u_long ctrack; /* current tracking set */
u_long ltrack; /* last tracking set */
@@ -4366,6 +4851,12 @@ sendcmd(
buf->idx = 2;
}
+void sendcmd P((struct txbuf *buf, int c));
+void sendbyte P((struct txbuf *buf, int b));
+void sendetx P((struct txbuf *buf, struct parseunit *parse));
+void sendint P((struct txbuf *buf, int a));
+void sendflt P((struct txbuf *buf, double a));
+
void
sendbyte(
struct txbuf *buf,
@@ -4451,7 +4942,16 @@ trimbletsip_setup(
{
u_char buffer[256];
struct txbuf buf;
+ trimble_t *t = parse->localdata;
+ if (t && t->last_reset &&
+ ((t->last_reset + TRIMBLE_RESET_HOLDOFF) > current_time)) {
+ return 1; /* not yet */
+ }
+
+ if (t)
+ t->last_reset = current_time;
+
buf.txt = buffer;
sendcmd(&buf, CMD_CVERSION); /* request software versions */
@@ -4466,7 +4966,7 @@ trimbletsip_setup(
sendetx(&buf, parse);
sendcmd(&buf, CMD_CMODESEL); /* fix mode select */
- sendbyte(&buf, 0); /* automatic */
+ sendbyte(&buf, 1); /* time transfer mode */
sendetx(&buf, parse);
sendcmd(&buf, CMD_CMESSAGE); /* request system message */
@@ -4512,9 +5012,10 @@ trimble_check(
if (current_time > t->last_msg + TRIMBLETSIP_IDLE_TIME)
(void)trimbletsip_setup(parse, "message timeout");
}
+
poll_poll(parse->peer); /* emit query string and re-arm timer */
- if (t->qtracking)
+ if (t && t->qtracking)
{
u_long oldsats = t->ltrack & ~t->ctrack;
@@ -4525,14 +5026,15 @@ trimble_check(
{
int i;
- for (i = 0; oldsats; i++)
+ for (i = 0; oldsats; i++) {
if (oldsats & (1 << i))
{
sendcmd(&buf, CMD_CSTATTRACK);
sendbyte(&buf, i+1); /* old sat */
sendetx(&buf, parse);
}
- oldsats &= ~(1 << i);
+ oldsats &= ~(1 << i);
+ }
}
sendcmd(&buf, CMD_CSTATTRACK);
@@ -4777,11 +5279,11 @@ trimbletsip_message(
if (s)
{
- sprintf(t, "%s=\"", s->varname);
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "%s=\"", s->varname);
}
else
{
- printf("TRIMBLE unknown command 0x%02x\n", cmd);
+ DPRINTF(1, ("TRIMBLE UNKNOWN COMMAND 0x%02x\n", cmd));
return;
}
@@ -4792,40 +5294,40 @@ trimbletsip_message(
switch(cmd)
{
case CMD_RCURTIME:
- sprintf(t, "%f, %d, %f",
- getflt((unsigned char *)&mb(0)), getshort((unsigned char *)&mb(4)),
- getflt((unsigned char *)&mb(6)));
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "%f, %d, %f",
+ getflt((unsigned char *)&mb(0)), getshort((unsigned char *)&mb(4)),
+ getflt((unsigned char *)&mb(6)));
break;
case CMD_RBEST4:
- strcpy(t, "mode: ");
+ strncpy(t, "mode: ", BUFFER_SIZE(pbuffer, t));
t += strlen(t);
switch (mb(0) & 0xF)
{
default:
- sprintf(t, "0x%x", mb(0) & 0x7);
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "0x%x", mb(0) & 0x7);
break;
case 1:
- strcat(t, "0D");
+ strncpy(t, "0D", BUFFER_SIZE(pbuffer, t));
break;
case 3:
- strcat(t, "2D");
+ strncpy(t, "2D", BUFFER_SIZE(pbuffer, t));
break;
case 4:
- strcat(t, "3D");
+ strncpy(t, "3D", BUFFER_SIZE(pbuffer, t));
break;
}
t += strlen(t);
if (mb(0) & 0x10)
- strcpy(t, "-MANUAL, ");
+ strncpy(t, "-MANUAL, ", BUFFER_SIZE(pbuffer, t));
else
- strcpy(t, "-AUTO, ");
+ strncpy(t, "-AUTO, ", BUFFER_SIZE(pbuffer, t));
t += strlen(t);
- sprintf(t, "satellites %02d %02d %02d %02d, PDOP %.2f, HDOP %.2f, VDOP %.2f, TDOP %.2f",
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "satellites %02d %02d %02d %02d, PDOP %.2f, HDOP %.2f, VDOP %.2f, TDOP %.2f",
mb(1), mb(2), mb(3), mb(4),
getflt((unsigned char *)&mb(5)),
getflt((unsigned char *)&mb(9)),
@@ -4835,7 +5337,7 @@ trimbletsip_message(
break;
case CMD_RVERSION:
- sprintf(t, "%d.%d (%d/%d/%d)",
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "%d.%d (%d/%d/%d)",
mb(0)&0xff, mb(1)&0xff, 1900+(mb(4)&0xff), mb(2)&0xff, mb(3)&0xff);
break;
@@ -4858,31 +5360,31 @@ trimbletsip_message(
switch (mb(0) & 0xFF)
{
default:
- sprintf(t, "illegal value 0x%02x", mb(0) & 0xFF);
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "illegal value 0x%02x", mb(0) & 0xFF);
break;
case 0x00:
- strcpy(t, "doing position fixes");
+ strncpy(t, "doing position fixes", BUFFER_SIZE(pbuffer, t));
break;
case 0x01:
- strcpy(t, "no GPS time yet");
+ strncpy(t, "no GPS time yet", BUFFER_SIZE(pbuffer, t));
break;
case 0x03:
- strcpy(t, "PDOP too high");
+ strncpy(t, "PDOP too high", BUFFER_SIZE(pbuffer, t));
break;
case 0x08:
- strcpy(t, "no usable satellites");
+ strncpy(t, "no usable satellites", BUFFER_SIZE(pbuffer, t));
break;
case 0x09:
- strcpy(t, "only ONE usable satellite");
+ strncpy(t, "only ONE usable satellite", BUFFER_SIZE(pbuffer, t));
break;
case 0x0A:
- strcpy(t, "only TWO usable satellites");
+ strncpy(t, "only TWO usable satellites", BUFFER_SIZE(pbuffer, t));
break;
case 0x0B:
- strcpy(t, "only THREE usable satellites");
+ strncpy(t, "only THREE usable satellites", BUFFER_SIZE(pbuffer, t));
break;
case 0x0C:
- strcpy(t, "the chosen satellite is unusable");
+ strncpy(t, "the chosen satellite is unusable", BUFFER_SIZE(pbuffer, t));
break;
}
@@ -4893,14 +5395,14 @@ trimbletsip_message(
for (i = 0; i < 8; i++)
if (bits & (0x1<<i))
{
- sprintf(t, ", %s", msgs[i]);
+ snprintf(t, BUFFER_SIZE(pbuffer, t), ", %s", msgs[i]);
t += strlen(t);
}
}
break;
case CMD_RMESSAGE:
- mkreadable(t, (int)(sizeof(pbuffer) - (t - pbuffer)), (char *)&mb(0), (unsigned)(size - 2 - (&mb(0) - buffer)), 0);
+ mkreadable(t, (int)BUFFER_SIZE(pbuffer, t), (char *)&mb(0), (unsigned)(size - 2 - (&mb(0) - buffer)), 0);
break;
case CMD_RMACHSTAT:
@@ -4919,7 +5421,7 @@ trimbletsip_message(
int i, bits;
- sprintf(t, "machine id 0x%02x", mb(0) & 0xFF);
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "machine id 0x%02x", mb(0) & 0xFF);
t += strlen(t);
bits = mb(1) & 0xFF;
@@ -4927,16 +5429,16 @@ trimbletsip_message(
for (i = 0; i < 8; i++)
if (bits & (0x1<<i))
{
- sprintf(t, ", %s", msgs[i]);
+ snprintf(t, BUFFER_SIZE(pbuffer, t), ", %s", msgs[i]);
t += strlen(t);
}
- sprintf(t, ", Superpackets %ssupported", (mb(2) & 0xFF) ? "" :"un" );
+ snprintf(t, BUFFER_SIZE(pbuffer, t), ", Superpackets %ssupported", (mb(2) & 0xFF) ? "" :"un" );
}
break;
case CMD_ROPERPARAM:
- sprintf(t, "%2x %.1f %.1f %.1f %.1f",
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "%2x %.1f %.1f %.1f %.1f",
mb(0), getflt((unsigned char *)&mb(1)), getflt((unsigned char *)&mb(5)),
getflt((unsigned char *)&mb(9)), getflt((unsigned char *)&mb(13)));
break;
@@ -4952,23 +5454,23 @@ trimbletsip_message(
if ((int)t0t != 0)
{
- mk_utcinfo(t, wnt, wnlsf, dn, dtls, dtlsf);
+ mk_utcinfo(t, wnt, wnlsf, dn, dtls, dtlsf, BUFFER_SIZE(pbuffer, t));
}
else
{
- strcpy(t, "<NO UTC DATA>");
+ strncpy(t, "<NO UTC DATA>", BUFFER_SIZE(pbuffer, t));
}
}
break;
case CMD_RSAT1BIAS:
- sprintf(t, "%.1fm %.2fm/s at %.1fs",
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "%.1fm %.2fm/s at %.1fs",
getflt(&mb(0)), getflt(&mb(4)), getflt(&mb(8)));
break;
case CMD_RIOOPTIONS:
{
- sprintf(t, "%02x %02x %02x %02x",
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "%02x %02x %02x %02x",
mb(0), mb(1), mb(2), mb(3));
if (mb(0) != TRIM_POS_OPT ||
mb(2) != TRIM_TIME_OPT)
@@ -4986,7 +5488,7 @@ trimbletsip_message(
double f = getflt((unsigned char *)&mb(12));
if (f > 0.0)
- sprintf(t, "x= %.1fm, y= %.1fm, z= %.1fm, time_of_fix= %f sec",
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "x= %.1fm, y= %.1fm, z= %.1fm, time_of_fix= %f sec",
x, y, z,
f);
else
@@ -5001,7 +5503,7 @@ trimbletsip_message(
double f = getflt((unsigned char *)&mb(12));
if (f > 0.0)
- sprintf(t, "lat %f %c, long %f %c, alt %.2fm",
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "lat %f %c, long %f %c, alt %.2fm",
((lat < 0.0) ? (-lat) : (lat))*RTOD, (lat < 0.0 ? 'S' : 'N'),
((lng < 0.0) ? (-lng) : (lng))*RTOD, (lng < 0.0 ? 'W' : 'E'),
getflt((unsigned char *)&mb(8)));
@@ -5015,7 +5517,7 @@ trimbletsip_message(
double x = getdbl((unsigned char *)&mb(0));
double y = getdbl((unsigned char *)&mb(8));
double z = getdbl((unsigned char *)&mb(16));
- sprintf(t, "x= %.1fm, y= %.1fm, z= %.1fm",
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "x= %.1fm, y= %.1fm, z= %.1fm",
x, y, z);
}
break;
@@ -5024,7 +5526,7 @@ trimbletsip_message(
{
double lat = getdbl((unsigned char *)&mb(0));
double lng = getdbl((unsigned char *)&mb(8));
- sprintf(t, "lat %f %c, lon %f %c, alt %.2fm",
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "lat %f %c, lon %f %c, alt %.2fm",
((lat < 0.0) ? (-lat) : (lat))*RTOD, (lat < 0.0 ? 'S' : 'N'),
((lng < 0.0) ? (-lng) : (lng))*RTOD, (lng < 0.0 ? 'W' : 'E'),
getdbl((unsigned char *)&mb(16)));
@@ -5035,32 +5537,32 @@ trimbletsip_message(
{
int i, sats;
- strcpy(t, "mode: ");
+ strncpy(t, "mode: ", BUFFER_SIZE(pbuffer, t));
t += strlen(t);
switch (mb(0) & 0x7)
{
default:
- sprintf(t, "0x%x", mb(0) & 0x7);
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "0x%x", mb(0) & 0x7);
break;
case 3:
- strcat(t, "2D");
+ strncpy(t, "2D", BUFFER_SIZE(pbuffer, t));
break;
case 4:
- strcat(t, "3D");
+ strncpy(t, "3D", BUFFER_SIZE(pbuffer, t));
break;
}
t += strlen(t);
if (mb(0) & 0x8)
- strcpy(t, "-MANUAL, ");
+ strncpy(t, "-MANUAL, ", BUFFER_SIZE(pbuffer, t));
else
- strcpy(t, "-AUTO, ");
+ strncpy(t, "-AUTO, ", BUFFER_SIZE(pbuffer, t));
t += strlen(t);
sats = (mb(0)>>4) & 0xF;
- sprintf(t, "PDOP %.2f, HDOP %.2f, VDOP %.2f, TDOP %.2f, %d satellite%s in view: ",
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "PDOP %.2f, HDOP %.2f, VDOP %.2f, TDOP %.2f, %d satellite%s in view: ",
getflt((unsigned char *)&mb(1)),
getflt((unsigned char *)&mb(5)),
getflt((unsigned char *)&mb(9)),
@@ -5070,7 +5572,7 @@ trimbletsip_message(
for (i=0; i < sats; i++)
{
- sprintf(t, "%s%02d", i ? ", " : "", mb(17+i));
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "%s%02d", i ? ", " : "", mb(17+i));
t += strlen(t);
if (tr)
tr->ctrack |= (1 << (mb(17+i)-1));
@@ -5085,17 +5587,17 @@ trimbletsip_message(
case CMD_RSTATTRACK:
{
- sprintf(t-2, "[%02d]=\"", mb(0)); /* add index to var name */
+ snprintf(t-2, BUFFER_SIZE(pbuffer, t-2), "[%02d]=\"", mb(0)); /* add index to var name */
t += strlen(t);
if (getflt((unsigned char *)&mb(4)) < 0.0)
{
- strcpy(t, "<NO MEASUREMENTS>");
+ strncpy(t, "<NO MEASUREMENTS>", BUFFER_SIZE(pbuffer, t));
var_flag &= ~DEF;
}
else
{
- sprintf(t, "ch=%d, acq=%s, eph=%d, signal_level= %5.2f, elevation= %5.2f, azimuth= %6.2f",
+ snprintf(t, BUFFER_SIZE(pbuffer, t), "ch=%d, acq=%s, eph=%d, signal_level= %5.2f, elevation= %5.2f, azimuth= %6.2f",
(mb(1) & 0xFF)>>3,
mb(2) ? ((mb(2) == 1) ? "ACQ" : "SRCH") : "NEVER",
mb(3),
@@ -5106,29 +5608,31 @@ trimbletsip_message(
if (mb(20))
{
var_flag &= ~DEF;
- strcpy(t, ", OLD");
+ strncpy(t, ", OLD", BUFFER_SIZE(pbuffer, t));
}
t += strlen(t);
if (mb(22))
{
if (mb(22) == 1)
- strcpy(t, ", BAD PARITY");
+ strncpy(t, ", BAD PARITY", BUFFER_SIZE(pbuffer, t));
else
if (mb(22) == 2)
- strcpy(t, ", BAD EPH HEALTH");
+ strncpy(t, ", BAD EPH HEALTH", BUFFER_SIZE(pbuffer, t));
}
t += strlen(t);
if (mb(23))
- strcpy(t, ", collecting data");
+ strncpy(t, ", collecting data", BUFFER_SIZE(pbuffer, t));
}
}
break;
default:
- strcpy(t, "<UNDECODED>");
+ strncpy(t, "<UNDECODED>", BUFFER_SIZE(pbuffer, t));
break;
}
- strcat(t,"\"");
+ t += strlen(t);
+
+ strncpy(t,"\"", BUFFER_SIZE(pbuffer, t));
set_var(&parse->kv, pbuffer, sizeof(pbuffer), var_flag);
}
}
@@ -5240,6 +5744,161 @@ int refclock_parse_bs;
* History:
*
* refclock_parse.c,v
+ * Revision 4.80 2007/08/11 12:06:29 kardel
+ * update comments wrt/ to PPS
+ *
+ * Revision 4.79 2007/08/11 11:52:23 kardel
+ * - terminate io bindings before io_closeclock() will close our file descriptor
+ *
+ * Revision 4.78 2006/12/22 20:08:27 kardel
+ * Bug 746 (RFE): add configuration for Expert mouseCLOCK USB v2.0 as mode 19
+ *
+ * Revision 4.77 2006/08/05 07:44:49 kardel
+ * support optionally separate PPS devices via /dev/refclockpps-{0..3}
+ *
+ * Revision 4.76 2006/06/22 18:40:47 kardel
+ * clean up signedness (gcc 4)
+ *
+ * Revision 4.75 2006/06/22 16:58:10 kardel
+ * Bug #632: call parse_ppsapi() in parse_ctl() when updating
+ * the PPS offset. Fix sign of offset passed to kernel.
+ *
+ * Revision 4.74 2006/06/18 21:18:37 kardel
+ * NetBSD Coverity CID 3796: possible NULL deref
+ *
+ * Revision 4.73 2006/05/26 14:23:46 kardel
+ * cleanup of copyright info
+ *
+ * Revision 4.72 2006/05/26 14:19:43 kardel
+ * cleanup of ioctl cruft
+ *
+ * Revision 4.71 2006/05/26 14:15:57 kardel
+ * delay adding refclock to async refclock io after all initializations
+ *
+ * Revision 4.70 2006/05/25 18:20:50 kardel
+ * bug #619
+ * terminate parse io engine after de-registering
+ * from refclock io engine
+ *
+ * Revision 4.69 2006/05/25 17:28:02 kardel
+ * complete refclock io structure initialization *before* inserting it into the
+ * refclock input machine (avoids null pointer deref) (bug #619)
+ *
+ * Revision 4.68 2006/05/01 17:02:51 kardel
+ * copy receiver method also for newlwy created receive buffers
+ *
+ * Revision 4.67 2006/05/01 14:37:29 kardel
+ * If an input buffer parses into more than one message do insert the
+ * parsed message in a new input buffer instead of processing it
+ * directly. This avoids deed complicated processing in signal
+ * handling.
+ *
+ * Revision 4.66 2006/03/18 00:45:30 kardel
+ * coverity fixes found in NetBSD coverity scan
+ *
+ * Revision 4.65 2006/01/26 06:08:33 kardel
+ * output errno on PPS setup failure
+ *
+ * Revision 4.64 2005/11/09 20:44:47 kardel
+ * utilize full PPS timestamp resolution from PPS API
+ *
+ * Revision 4.63 2005/10/07 22:10:25 kardel
+ * bounded buffer implementation
+ *
+ * Revision 4.62.2.2 2005/09/25 10:20:16 kardel
+ * avoid unexpected buffer overflows due to sprintf("%f") on strange floats:
+ * replace almost all str* and *printf functions be their buffer bounded
+ * counterparts
+ *
+ * Revision 4.62.2.1 2005/08/27 16:19:27 kardel
+ * limit re-set rate of trimble clocks
+ *
+ * Revision 4.62 2005/08/06 17:40:00 kardel
+ * cleanup size handling wrt/ to buffer boundaries
+ *
+ * Revision 4.61 2005/07/27 21:16:19 kardel
+ * fix a long (> 11 years) misconfiguration wrt/ Meinberg cflag factory
+ * default setup. CSTOPB was missing for the 7E2 default data format of
+ * the DCF77 clocks.
+ *
+ * Revision 4.60 2005/07/17 21:14:44 kardel
+ * change contents of version string to include the RCS/CVS Id
+ *
+ * Revision 4.59 2005/07/06 06:56:38 kardel
+ * syntax error
+ *
+ * Revision 4.58 2005/07/04 13:10:40 kardel
+ * fix bug 455: tripping over NULL pointer on cleanup
+ * fix shadow storage logic for ppsphaseadjust and trustime wrt/ time2
+ * fix compiler warnings for some platforms wrt/ printf formatstrings and
+ * varying structure element sizes
+ * reorder assignment in binding to avoid tripping over NULL pointers
+ *
+ * Revision 4.57 2005/06/25 09:25:19 kardel
+ * sort out log output sequence
+ *
+ * Revision 4.56 2005/06/14 21:47:27 kardel
+ * collect samples only if samples are ok (sync or trusted flywheel)
+ * propagate pps phase adjustment value to kernel via PPSAPI to help HARDPPS
+ * en- and dis-able HARDPPS in correlation to receiver sync state
+ *
+ * Revision 4.55 2005/06/02 21:28:31 kardel
+ * clarify trust logic
+ *
+ * Revision 4.54 2005/06/02 17:06:49 kardel
+ * change status reporting to use fixed refclock_report()
+ *
+ * Revision 4.53 2005/06/02 16:33:31 kardel
+ * fix acceptance of clocks unsync clocks right at start
+ *
+ * Revision 4.52 2005/05/26 21:55:06 kardel
+ * cleanup status reporting
+ *
+ * Revision 4.51 2005/05/26 19:19:14 kardel
+ * implement fast refclock startup
+ *
+ * Revision 4.50 2005/04/16 20:51:35 kardel
+ * set pps_enable = 1 when binding a kernel PPS source
+ *
+ * Revision 4.49 2005/04/16 17:29:26 kardel
+ * add non polling clock type 18 for just listenning to Meinberg clocks
+ *
+ * Revision 4.48 2005/04/16 16:22:27 kardel
+ * bk sync 20050415 ntp-dev
+ *
+ * Revision 4.47 2004/11/29 10:42:48 kardel
+ * bk sync ntp-dev 20041129
+ *
+ * Revision 4.46 2004/11/29 10:26:29 kardel
+ * keep fudgetime2 in sync with trusttime/ppsphaseadjust depending in flag1
+ *
+ * Revision 4.45 2004/11/14 20:53:20 kardel
+ * clear PPS flags after using them
+ *
+ * Revision 4.44 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.43 2001/05/26 22:53:16 kardel
+ * 20010526 reconcilation
+ *
+ * Revision 4.42 2000/05/14 15:31:51 kardel
+ * PPSAPI && RAWDCF modemline support
+ *
+ * Revision 4.41 2000/04/09 19:50:45 kardel
+ * fixed rawdcfdtr_init() -> rawdcf_init_1
+ *
+ * Revision 4.40 2000/04/09 15:27:55 kardel
+ * modem line fiddle in rawdcf_init_2
+ *
+ * Revision 4.39 2000/03/18 09:16:55 kardel
+ * PPSAPI integration
+ *
+ * Revision 4.38 2000/03/05 20:25:06 kardel
+ * support PPSAPI
+ *
+ * Revision 4.37 2000/03/05 20:11:14 kardel
+ * 4.0.99g reconcilation
+ *
* Revision 4.36 1999/11/28 17:18:20 kardel
* disabled burst mode
*
OpenPOWER on IntegriCloud