summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/ntpd/refclock_parse.c
diff options
context:
space:
mode:
authorroberto <roberto@FreeBSD.org>2008-08-17 17:37:33 +0000
committerroberto <roberto@FreeBSD.org>2008-08-17 17:37:33 +0000
commit4ded1c1fa0bc21c61f91a2dbe864835986745121 (patch)
tree16d100fbc9dae63888d48b464e471ba0e5065193 /contrib/ntp/ntpd/refclock_parse.c
parent8b5a86d4fda08a9c68231415812edcb26be52f79 (diff)
downloadFreeBSD-src-4ded1c1fa0bc21c61f91a2dbe864835986745121.zip
FreeBSD-src-4ded1c1fa0bc21c61f91a2dbe864835986745121.tar.gz
Flatten the dist and various 4.n.n trees in preparation of future ntp imports.
Diffstat (limited to 'contrib/ntp/ntpd/refclock_parse.c')
-rw-r--r--contrib/ntp/ntpd/refclock_parse.c5386
1 files changed, 0 insertions, 5386 deletions
diff --git a/contrib/ntp/ntpd/refclock_parse.c b/contrib/ntp/ntpd/refclock_parse.c
deleted file mode 100644
index 52fadaa..0000000
--- a/contrib/ntp/ntpd/refclock_parse.c
+++ /dev/null
@@ -1,5386 +0,0 @@
-/*
- * /src/NTP/ntp-4/ntpd/refclock_parse.c,v 4.36 1999/11/28 17:18:20 kardel RELEASE_19991128_A
- *
- * refclock_parse.c,v 4.36 1999/11/28 17:18:20 kardel RELEASE_19991128_A
- *
- * generic reference clock driver for 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
- *
- * 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.
- *
- * Copyright (c) 1995-1999 by Frank Kardel <kardel@acm.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.
- *
- * 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.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if defined(REFCLOCK) && defined(CLOCK_PARSE)
-
-/*
- * This driver currently provides the support for
- * - Meinberg receiver DCF77 PZF 535 (TCXO version) (DCF)
- * - Meinberg receiver DCF77 PZF 535 (OCXO version) (DCF)
- * - Meinberg receiver DCF77 PZF 509 (DCF)
- * - Meinberg receiver DCF77 AM receivers (e.g. C51) (DCF)
- * - IGEL CLOCK (DCF)
- * - ELV DCF7000 (DCF)
- * - Schmid clock (DCF)
- * - Conrad DCF77 receiver module (DCF)
- * - FAU DCF77 NTP receiver (TimeBrick) (DCF)
- *
- * - Meinberg GPS166/GPS167 (GPS)
- * - Trimble (TSIP and TAIP protocol) (GPS)
- *
- * - RCC8000 MSF Receiver (MSF)
- * - WHARTON 400A Series clock (DCF)
- * - VARITEXT clock (MSF)
- */
-
-/*
- * Meinberg receivers are usually connected via a
- * 9600 baud serial line
- *
- * The Meinberg GPS receivers also have a special NTP time stamp
- * format. The firmware release is Uni-Erlangen.
- *
- * Meinberg generic receiver setup:
- * output time code every second
- * Baud rate 9600 7E2S
- *
- * Meinberg GPS16x setup:
- * output time code every second
- * Baudrate 19200 8N1
- *
- * This software supports the standard data formats used
- * in Meinberg receivers.
- *
- * Special software versions are only sensible for the
- * GPS 16x family of receivers.
- *
- * Meinberg can be reached via: http://www.meinberg.de/
- */
-
-#include "ntpd.h"
-#include "ntp_refclock.h"
-#include "ntp_unixtime.h" /* includes <sys/time.h> */
-#include "ntp_control.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#ifndef TM_IN_SYS_TIME
-# include <time.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
-
-#ifdef STREAM
-# include <sys/stream.h>
-# include <sys/stropts.h>
-#endif
-
-#ifdef HAVE_TERMIOS
-# define TTY_GETATTR(_FD_, _ARG_) tcgetattr((_FD_), (_ARG_))
-# define TTY_SETATTR(_FD_, _ARG_) tcsetattr((_FD_), TCSANOW, (_ARG_))
-# undef HAVE_SYSV_TTYS
-#endif
-
-#ifdef HAVE_SYSV_TTYS
-# define TTY_GETATTR(_FD_, _ARG_) ioctl((_FD_), TCGETA, (_ARG_))
-# define TTY_SETATTR(_FD_, _ARG_) ioctl((_FD_), TCSETAW, (_ARG_))
-#endif
-
-#ifdef HAVE_BSD_TTYS
-/* #error CURRENTLY NO BSD TTY SUPPORT */
-# include "Bletch: BSD TTY not currently supported"
-#endif
-
-#ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-
-#ifdef PPS
-#ifdef HAVE_SYS_PPSCLOCK_H
-#include <sys/ppsclock.h>
-#endif
-#ifdef HAVE_TIO_SERIAL_STUFF
-#include <linux/serial.h>
-#endif
-#endif
-
-#include "ntp_io.h"
-#include "ntp_stdlib.h"
-
-#include "parse.h"
-#include "mbg_gps166.h"
-#include "trimble.h"
-#include "binio.h"
-#include "ascii.h"
-#include "ieee754io.h"
-
-static char rcsid[]="refclock_parse.c,v 4.36 1999/11/28 17:18:20 kardel RELEASE_19991128_A";
-
-/**===========================================================================
- ** 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,
- NOFLAGS
-};
-
-/*
- * Definitions
- */
-#define MAXUNITS 4 /* maximum number of "PARSE" units permitted */
-#define PARSEDEVICE "/dev/refclock-%d" /* device to open %d is unit number */
-
-#undef ABS
-#define ABS(_X_) (((_X_) < 0) ? -(_X_) : (_X_))
-
-/**===========================================================================
- ** function vector for dynamically binding io handling mechanism
- **/
-
-struct parseunit; /* to keep inquiring minds happy */
-
-typedef struct bind
-{
- const char *bd_description; /* name of type of binding */
- int (*bd_init) P((struct parseunit *)); /* initialize */
- void (*bd_end) P((struct parseunit *)); /* end */
- int (*bd_setcs) P((struct parseunit *, parsectl_t *)); /* set character size */
- int (*bd_disable) P((struct parseunit *)); /* disable */
- int (*bd_enable) P((struct parseunit *)); /* enable */
- int (*bd_getfmt) P((struct parseunit *, parsectl_t *)); /* get format */
- int (*bd_setfmt) P((struct parseunit *, parsectl_t *)); /* setfmt */
- int (*bd_timecode) P((struct parseunit *, parsectl_t *)); /* get time code */
- void (*bd_receive) P((struct recvbuf *)); /* receive operation */
- int (*bd_io_input) P((struct recvbuf *)); /* input operation */
-} bind_t;
-
-#define PARSE_END(_X_) (*(_X_)->binding->bd_end)(_X_)
-#define PARSE_SETCS(_X_, _CS_) (*(_X_)->binding->bd_setcs)(_X_, _CS_)
-#define PARSE_ENABLE(_X_) (*(_X_)->binding->bd_enable)(_X_)
-#define PARSE_DISABLE(_X_) (*(_X_)->binding->bd_disable)(_X_)
-#define PARSE_GETFMT(_X_, _DCT_) (*(_X_)->binding->bd_getfmt)(_X_, _DCT_)
-#define PARSE_SETFMT(_X_, _DCT_) (*(_X_)->binding->bd_setfmt)(_X_, _DCT_)
-#define PARSE_GETTIMECODE(_X_, _DCT_) (*(_X_)->binding->bd_timecode)(_X_, _DCT_)
-
-/*
- * io modes
- */
-#define PARSE_F_PPSPPS 0x0001 /* use loopfilter PPS code (CIOGETEV) */
-#define PARSE_F_PPSONSECOND 0x0002 /* PPS pulses are on second */
-
-
-/**===========================================================================
- ** error message regression handling
- **
- ** there are quite a few errors that can occur in rapid succession such as
- ** noisy input data or no data at all. in order to reduce the amount of
- ** syslog messages in such case, we are using a backoff algorithm. We limit
- ** the number of error messages of a certain class to 1 per time unit. if a
- ** configurable number of messages is displayed that way, we move on to the
- ** next time unit / count for that class. a count of messages that have been
- ** suppressed is held and displayed whenever a corresponding message is
- ** displayed. the time units for a message class will also be displayed.
- ** whenever an error condition clears we reset the error message state,
- ** thus we would still generate much output on pathological conditions
- ** where the system oscillates between OK and NOT OK states. coping
- ** with that condition is currently considered too complicated.
- **/
-
-#define ERR_ALL (unsigned)~0 /* "all" errors */
-#define ERR_BADDATA (unsigned)0 /* unusable input data/conversion errors */
-#define ERR_NODATA (unsigned)1 /* no input data */
-#define ERR_BADIO (unsigned)2 /* read/write/select errors */
-#define ERR_BADSTATUS (unsigned)3 /* unsync states */
-#define ERR_BADEVENT (unsigned)4 /* non nominal events */
-#define ERR_INTERNAL (unsigned)5 /* internal error */
-#define ERR_CNT (unsigned)(ERR_INTERNAL+1)
-
-#define ERR(_X_) if (list_err(parse, (_X_)))
-
-struct errorregression
-{
- u_long err_count; /* number of repititions per class */
- u_long err_delay; /* minimum delay between messages */
-};
-
-static struct errorregression
-err_baddata[] = /* error messages for bad input data */
-{
- { 1, 0 }, /* output first message immediately */
- { 5, 60 }, /* output next five messages in 60 second intervals */
- { 3, 3600 }, /* output next 3 messages in hour intervals */
- { 0, 12*3600 } /* repeat messages only every 12 hours */
-};
-
-static struct errorregression
-err_nodata[] = /* error messages for missing input data */
-{
- { 1, 0 }, /* output first message immediately */
- { 5, 60 }, /* output next five messages in 60 second intervals */
- { 3, 3600 }, /* output next 3 messages in hour intervals */
- { 0, 12*3600 } /* repeat messages only every 12 hours */
-};
-
-static struct errorregression
-err_badstatus[] = /* unsynchronized state messages */
-{
- { 1, 0 }, /* output first message immediately */
- { 5, 60 }, /* output next five messages in 60 second intervals */
- { 3, 3600 }, /* output next 3 messages in hour intervals */
- { 0, 12*3600 } /* repeat messages only every 12 hours */
-};
-
-static struct errorregression
-err_badio[] = /* io failures (bad reads, selects, ...) */
-{
- { 1, 0 }, /* output first message immediately */
- { 5, 60 }, /* output next five messages in 60 second intervals */
- { 5, 3600 }, /* output next 3 messages in hour intervals */
- { 0, 12*3600 } /* repeat messages only every 12 hours */
-};
-
-static struct errorregression
-err_badevent[] = /* non nominal events */
-{
- { 20, 0 }, /* output first message immediately */
- { 6, 60 }, /* output next five messages in 60 second intervals */
- { 5, 3600 }, /* output next 3 messages in hour intervals */
- { 0, 12*3600 } /* repeat messages only every 12 hours */
-};
-
-static struct errorregression
-err_internal[] = /* really bad things - basically coding/OS errors */
-{
- { 0, 0 }, /* output all messages immediately */
-};
-
-static struct errorregression *
-err_tbl[] =
-{
- err_baddata,
- err_nodata,
- err_badio,
- err_badstatus,
- err_badevent,
- err_internal
-};
-
-struct errorinfo
-{
- u_long err_started; /* begin time (ntp) of error condition */
- u_long err_last; /* last time (ntp) error occurred */
- u_long err_cnt; /* number of error repititions */
- u_long err_suppressed; /* number of suppressed messages */
- struct errorregression *err_stage; /* current error stage */
-};
-
-/**===========================================================================
- ** refclock instance data
- **/
-
-struct parseunit
-{
- /*
- * NTP management
- */
- struct peer *peer; /* backlink to peer structure - refclock inactive if 0 */
- struct refclockproc *generic; /* backlink to refclockproc structure */
-
- /*
- * PARSE io
- */
- bind_t *binding; /* io handling binding */
-
- /*
- * parse state
- */
- parse_t parseio; /* io handling structure (user level parsing) */
-
- /*
- * type specific parameters
- */
- struct parse_clockinfo *parse_type; /* link to clock description */
-
- /*
- * clock state handling/reporting
- */
- u_char flags; /* flags (leap_control) */
- u_long lastchange; /* time (ntp) when last state change accured */
- u_long statetime[CEVNT_MAX+1]; /* accumulated time of clock states */
- 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 ppsserial; /* magic cookie for ppsclock serials (avoids stale ppsclock data) */
- parsetime_t time; /* 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 */
- struct ctl_var *kv; /* additional pseudo variables */
- u_long laststatistic; /* time when staticstics where output */
-};
-
-
-/**===========================================================================
- ** Clockinfo section all parameter for specific clock types
- ** includes NTP parameters, TTY parameters and IO handling parameters
- **/
-
-static void poll_dpoll P((struct parseunit *));
-static void poll_poll P((struct peer *));
-static int poll_init P((struct parseunit *));
-
-typedef struct poll_info
-{
- u_long rate; /* poll rate - once every "rate" seconds - 0 off */
- const char *string; /* string to send for polling */
- u_long count; /* number of characters in string */
-} poll_info_t;
-
-#define NO_CL_FLAGS 0
-#define NO_POLL 0
-#define NO_INIT 0
-#define NO_END 0
-#define NO_EVENT 0
-#define NO_DATA 0
-#define NO_MESSAGE 0
-#define NO_PPSDELAY 0
-
-#define DCF_ID "DCF" /* generic DCF */
-#define DCF_A_ID "DCFa" /* AM demodulation */
-#define DCF_P_ID "DCFp" /* psuedo random phase shift */
-#define GPS_ID "GPS" /* GPS receiver */
-
-#define NOCLOCK_ROOTDELAY 0.0
-#define NOCLOCK_BASEDELAY 0.0
-#define NOCLOCK_DESCRIPTION 0
-#define NOCLOCK_MAXUNSYNC 0
-#define NOCLOCK_CFLAG 0
-#define NOCLOCK_IFLAG 0
-#define NOCLOCK_OFLAG 0
-#define NOCLOCK_LFLAG 0
-#define NOCLOCK_ID "TILT"
-#define NOCLOCK_POLL NO_POLL
-#define NOCLOCK_INIT NO_INIT
-#define NOCLOCK_END NO_END
-#define NOCLOCK_DATA NO_DATA
-#define NOCLOCK_FORMAT ""
-#define NOCLOCK_TYPE CTL_SST_TS_UNSPEC
-#define NOCLOCK_SAMPLES 0
-#define NOCLOCK_KEEP 0
-
-#define DCF_TYPE CTL_SST_TS_LF
-#define GPS_TYPE CTL_SST_TS_UHF
-
-/*
- * receiver specific constants
- */
-#define MBG_SPEED (B9600)
-#define MBG_CFLAG (CS7|PARENB|CREAD|CLOCAL|HUPCL)
-#define MBG_IFLAG (IGNBRK|IGNPAR|ISTRIP)
-#define MBG_OFLAG 0
-#define MBG_LFLAG 0
-#define MBG_FLAGS PARSE_F_PPSONSECOND
-
-/*
- * Meinberg DCF77 receivers
- */
-#define DCFUA31_ROOTDELAY 0.0 /* 0 */
-#define DCFUA31_BASEDELAY 0.010 /* 10.7421875ms: 10 ms (+/- 3 ms) */
-#define DCFUA31_DESCRIPTION "Meinberg DCF77 C51 or compatible"
-#define DCFUA31_MAXUNSYNC 60*30 /* only trust clock for 1/2 hour */
-#define DCFUA31_SPEED MBG_SPEED
-#define DCFUA31_CFLAG MBG_CFLAG
-#define DCFUA31_IFLAG MBG_IFLAG
-#define DCFUA31_OFLAG MBG_OFLAG
-#define DCFUA31_LFLAG MBG_LFLAG
-#define DCFUA31_SAMPLES 5
-#define DCFUA31_KEEP 3
-#define DCFUA31_FORMAT "Meinberg Standard"
-
-/*
- * Meinberg DCF PZF535/TCXO (FM/PZF) receiver
- */
-#define DCFPZF535_ROOTDELAY 0.0
-#define DCFPZF535_BASEDELAY 0.001968 /* 1.968ms +- 104us (oscilloscope) - relative to start (end of STX) */
-#define DCFPZF535_DESCRIPTION "Meinberg DCF PZF 535/509 / TCXO"
-#define DCFPZF535_MAXUNSYNC 60*60*12 /* only trust clock for 12 hours
- * @ 5e-8df/f we have accumulated
- * at most 2.16 ms (thus we move to
- * NTP synchronisation */
-#define DCFPZF535_SPEED MBG_SPEED
-#define DCFPZF535_CFLAG MBG_CFLAG
-#define DCFPZF535_IFLAG MBG_IFLAG
-#define DCFPZF535_OFLAG MBG_OFLAG
-#define DCFPZF535_LFLAG MBG_LFLAG
-#define DCFPZF535_SAMPLES 5
-#define DCFPZF535_KEEP 3
-#define DCFPZF535_FORMAT "Meinberg Standard"
-
-/*
- * Meinberg DCF PZF535/OCXO receiver
- */
-#define DCFPZF535OCXO_ROOTDELAY 0.0
-#define DCFPZF535OCXO_BASEDELAY 0.001968 /* 1.968ms +- 104us (oscilloscope) - relative to start (end of STX) */
-#define DCFPZF535OCXO_DESCRIPTION "Meinberg DCF PZF 535/509 / OCXO"
-#define DCFPZF535OCXO_MAXUNSYNC 60*60*96 /* only trust clock for 4 days
- * @ 5e-9df/f we have accumulated
- * at most an error of 1.73 ms
- * (thus we move to NTP synchronisation) */
-#define DCFPZF535OCXO_SPEED MBG_SPEED
-#define DCFPZF535OCXO_CFLAG MBG_CFLAG
-#define DCFPZF535OCXO_IFLAG MBG_IFLAG
-#define DCFPZF535OCXO_OFLAG MBG_OFLAG
-#define DCFPZF535OCXO_LFLAG MBG_LFLAG
-#define DCFPZF535OCXO_SAMPLES 5
-#define DCFPZF535OCXO_KEEP 3
-#define DCFPZF535OCXO_FORMAT "Meinberg Standard"
-
-/*
- * Meinberg GPS16X receiver
- */
-static void gps16x_message P((struct parseunit *, parsetime_t *));
-static int gps16x_poll_init P((struct parseunit *));
-
-#define GPS16X_ROOTDELAY 0.0 /* nothing here */
-#define GPS16X_BASEDELAY 0.001968 /* XXX to be fixed ! 1.968ms +- 104us (oscilloscope) - relative to start (end of STX) */
-#define GPS16X_DESCRIPTION "Meinberg GPS16x receiver"
-#define GPS16X_MAXUNSYNC 60*60*96 /* only trust clock for 4 days
- * @ 5e-9df/f we have accumulated
- * at most an error of 1.73 ms
- * (thus we move to NTP synchronisation) */
-#define GPS16X_SPEED B19200
-#define GPS16X_CFLAG (CS8|CREAD|CLOCAL|HUPCL)
-#define GPS16X_IFLAG (IGNBRK|IGNPAR)
-#define GPS16X_OFLAG MBG_OFLAG
-#define GPS16X_LFLAG MBG_LFLAG
-#define GPS16X_POLLRATE 6
-#define GPS16X_POLLCMD ""
-#define GPS16X_CMDSIZE 0
-
-static poll_info_t gps16x_pollinfo = { GPS16X_POLLRATE, GPS16X_POLLCMD, GPS16X_CMDSIZE };
-
-#define GPS16X_INIT gps16x_poll_init
-#define GPS16X_POLL 0
-#define GPS16X_END 0
-#define GPS16X_DATA ((void *)(&gps16x_pollinfo))
-#define GPS16X_MESSAGE gps16x_message
-#define GPS16X_ID GPS_ID
-#define GPS16X_FORMAT "Meinberg GPS Extended"
-#define GPS16X_SAMPLES 5
-#define GPS16X_KEEP 3
-
-/*
- * ELV DCF7000 Wallclock-Receiver/Switching Clock (Kit)
- *
- * This is really not the hottest clock - but before you have nothing ...
- */
-#define DCF7000_ROOTDELAY 0.0 /* 0 */
-#define DCF7000_BASEDELAY 0.405 /* slow blow */
-#define DCF7000_DESCRIPTION "ELV DCF7000"
-#define DCF7000_MAXUNSYNC (60*5) /* sorry - but it just was not build as a clock */
-#define DCF7000_SPEED (B9600)
-#define DCF7000_CFLAG (CS8|CREAD|PARENB|PARODD|CLOCAL|HUPCL)
-#define DCF7000_IFLAG (IGNBRK)
-#define DCF7000_OFLAG 0
-#define DCF7000_LFLAG 0
-#define DCF7000_SAMPLES 5
-#define DCF7000_KEEP 3
-#define DCF7000_FORMAT "ELV DCF7000"
-
-/*
- * Schmid DCF Receiver Kit
- *
- * When the WSDCF clock is operating optimally we want the primary clock
- * distance to come out at 300 ms. Thus, peer.distance in the WSDCF peer
- * structure is set to 290 ms and we compute delays which are at least
- * 10 ms long. The following are 290 ms and 10 ms expressed in u_fp format
- */
-#define WS_POLLRATE 1 /* every second - watch interdependency with poll routine */
-#define WS_POLLCMD "\163"
-#define WS_CMDSIZE 1
-
-static poll_info_t wsdcf_pollinfo = { WS_POLLRATE, WS_POLLCMD, WS_CMDSIZE };
-
-#define WSDCF_INIT poll_init
-#define WSDCF_POLL poll_dpoll
-#define WSDCF_END 0
-#define WSDCF_DATA ((void *)(&wsdcf_pollinfo))
-#define WSDCF_ROOTDELAY 0.0 /* 0 */
-#define WSDCF_BASEDELAY 0.010 /* ~ 10ms */
-#define WSDCF_DESCRIPTION "WS/DCF Receiver"
-#define WSDCF_FORMAT "Schmid"
-#define WSDCF_MAXUNSYNC (60*60) /* assume this beast hold at 1 h better than 2 ms XXX-must verify */
-#define WSDCF_SPEED (B1200)
-#define WSDCF_CFLAG (CS8|CREAD|CLOCAL)
-#define WSDCF_IFLAG 0
-#define WSDCF_OFLAG 0
-#define WSDCF_LFLAG 0
-#define WSDCF_SAMPLES 5
-#define WSDCF_KEEP 3
-
-/*
- * RAW DCF77 - input of DCF marks via RS232 - many variants
- */
-#define RAWDCF_FLAGS 0
-#define RAWDCF_ROOTDELAY 0.0 /* 0 */
-#define RAWDCF_BASEDELAY 0.258
-#define RAWDCF_FORMAT "RAW DCF77 Timecode"
-#define RAWDCF_MAXUNSYNC (0) /* sorry - its a true receiver - no signal - no time */
-#define RAWDCF_SPEED (B50)
-#ifdef NO_PARENB_IGNPAR /* Was: defined(SYS_IRIX4) || defined(SYS_IRIX5) */
-/* somehow doesn't grok PARENB & IGNPAR (mj) */
-# define RAWDCF_CFLAG (CS8|CREAD|CLOCAL)
-#else
-# define RAWDCF_CFLAG (CS8|CREAD|CLOCAL|PARENB)
-#endif
-#ifdef RAWDCF_NO_IGNPAR /* Was: defined(SYS_LINUX) && defined(CLOCK_RAWDCF) */
-# define RAWDCF_IFLAG 0
-#else
-# define RAWDCF_IFLAG (IGNPAR)
-#endif
-#define RAWDCF_OFLAG 0
-#define RAWDCF_LFLAG 0
-#define RAWDCF_SAMPLES 20
-#define RAWDCF_KEEP 12
-#define RAWDCF_INIT 0
-
-/*
- * RAW DCF variants
- */
-/*
- * Conrad receiver
- *
- * simplest (cheapest) DCF clock - e. g. DCF77 receiver by Conrad
- * (~40DM - roughly $30 ) followed by a level converter for RS232
- */
-#define CONRAD_BASEDELAY 0.292 /* Conrad receiver @ 50 Baud on a Sun */
-#define CONRAD_DESCRIPTION "RAW DCF77 CODE (Conrad DCF77 receiver module)"
-
-/*
- * TimeBrick receiver
- */
-#define TIMEBRICK_BASEDELAY 0.210 /* TimeBrick @ 50 Baud on a Sun */
-#define TIMEBRICK_DESCRIPTION "RAW DCF77 CODE (TimeBrick)"
-
-/*
- * IGEL:clock receiver
- */
-#define IGELCLOCK_BASEDELAY 0.258 /* IGEL:clock receiver */
-#define IGELCLOCK_DESCRIPTION "RAW DCF77 CODE (IGEL:clock)"
-#define IGELCLOCK_SPEED (B1200)
-#define IGELCLOCK_CFLAG (CS8|CREAD|HUPCL|CLOCAL)
-
-/*
- * RAWDCF receivers that need to be powered from DTR
- * (like Expert mouse clock)
- */
-static int rawdcf_init_1 P((struct parseunit *));
-#define RAWDCFDTRSET_DESCRIPTION "RAW DCF77 CODE (DTR SET/RTS CLR)"
-#define RAWDCFDTRSET_INIT rawdcf_init_1
-
-/*
- * RAWDCF receivers that need to be powered from
- * DTR CLR and RTS SET
- */
-static int rawdcf_init_2 P((struct parseunit *));
-#define RAWDCFDTRCLRRTSSET_DESCRIPTION "RAW DCF77 CODE (DTR CLR/RTS SET)"
-#define RAWDCFDTRCLRRTSSET_INIT rawdcf_init_2
-
-/*
- * Trimble GPS receivers (TAIP and TSIP protocols)
- */
-#ifndef TRIM_POLLRATE
-#define TRIM_POLLRATE 0 /* only true direct polling */
-#endif
-
-#define TRIM_TAIPPOLLCMD ">SRM;FR_FLAG=F;EC_FLAG=F<>QTM<"
-#define TRIM_TAIPCMDSIZE (sizeof(TRIM_TAIPPOLLCMD)-1)
-
-static poll_info_t trimbletaip_pollinfo = { TRIM_POLLRATE, TRIM_TAIPPOLLCMD, TRIM_TAIPCMDSIZE };
-static int trimbletaip_init P((struct parseunit *));
-static void trimbletaip_event P((struct parseunit *, int));
-
-/* query time & UTC correction data */
-static char tsipquery[] = { DLE, 0x21, DLE, ETX, DLE, 0x2F, DLE, ETX };
-
-static poll_info_t trimbletsip_pollinfo = { TRIM_POLLRATE, tsipquery, sizeof(tsipquery) };
-static int trimbletsip_init P((struct parseunit *));
-static void trimbletsip_end P((struct parseunit *));
-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 TRIMBLETAIP_SPEED (B4800)
-#define TRIMBLETAIP_CFLAG (CS8|CREAD|CLOCAL)
-#define TRIMBLETAIP_IFLAG (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON)
-#define TRIMBLETAIP_OFLAG (OPOST|ONLCR)
-#define TRIMBLETAIP_LFLAG (0)
-
-#define TRIMBLETSIP_SPEED (B9600)
-#define TRIMBLETSIP_CFLAG (CS8|CLOCAL|CREAD|PARENB|PARODD)
-#define TRIMBLETSIP_IFLAG (IGNBRK)
-#define TRIMBLETSIP_OFLAG (0)
-#define TRIMBLETSIP_LFLAG (ICANON)
-
-#define TRIMBLETSIP_SAMPLES 5
-#define TRIMBLETSIP_KEEP 3
-#define TRIMBLETAIP_SAMPLES 5
-#define TRIMBLETAIP_KEEP 3
-
-#define TRIMBLETAIP_FLAGS (PARSE_F_PPSONSECOND)
-#define TRIMBLETSIP_FLAGS (TRIMBLETAIP_FLAGS)
-
-#define TRIMBLETAIP_POLL poll_dpoll
-#define TRIMBLETSIP_POLL poll_dpoll
-
-#define TRIMBLETAIP_INIT trimbletaip_init
-#define TRIMBLETSIP_INIT trimbletsip_init
-
-#define TRIMBLETAIP_EVENT trimbletaip_event
-
-#define TRIMBLETSIP_EVENT trimbletsip_event
-#define TRIMBLETSIP_MESSAGE trimbletsip_message
-
-#define TRIMBLETAIP_END 0
-#define TRIMBLETSIP_END trimbletsip_end
-
-#define TRIMBLETAIP_DATA ((void *)(&trimbletaip_pollinfo))
-#define TRIMBLETSIP_DATA ((void *)(&trimbletsip_pollinfo))
-
-#define TRIMBLETAIP_ID GPS_ID
-#define TRIMBLETSIP_ID GPS_ID
-
-#define TRIMBLETAIP_FORMAT "Trimble TAIP"
-#define TRIMBLETSIP_FORMAT "Trimble TSIP"
-
-#define TRIMBLETAIP_ROOTDELAY 0x0
-#define TRIMBLETSIP_ROOTDELAY 0x0
-
-#define TRIMBLETAIP_BASEDELAY 0.0
-#define TRIMBLETSIP_BASEDELAY 0.020 /* GPS time message latency */
-
-#define TRIMBLETAIP_DESCRIPTION "Trimble GPS (TAIP) receiver"
-#define TRIMBLETSIP_DESCRIPTION "Trimble GPS (TSIP) receiver"
-
-#define TRIMBLETAIP_MAXUNSYNC 0
-#define TRIMBLETSIP_MAXUNSYNC 0
-
-#define TRIMBLETAIP_EOL '<'
-
-/*
- * RadioCode Clocks RCC 800 receiver
- */
-#define RCC_POLLRATE 0 /* only true direct polling */
-#define RCC_POLLCMD "\r"
-#define RCC_CMDSIZE 1
-
-static poll_info_t rcc8000_pollinfo = { RCC_POLLRATE, RCC_POLLCMD, RCC_CMDSIZE };
-#define RCC8000_FLAGS 0
-#define RCC8000_POLL poll_dpoll
-#define RCC8000_INIT poll_init
-#define RCC8000_END 0
-#define RCC8000_DATA ((void *)(&rcc8000_pollinfo))
-#define RCC8000_ROOTDELAY 0.0
-#define RCC8000_BASEDELAY 0.0
-#define RCC8000_ID "MSF"
-#define RCC8000_DESCRIPTION "RCC 8000 MSF Receiver"
-#define RCC8000_FORMAT "Radiocode RCC8000"
-#define RCC8000_MAXUNSYNC (60*60) /* should be ok for an hour */
-#define RCC8000_SPEED (B2400)
-#define RCC8000_CFLAG (CS8|CREAD|CLOCAL)
-#define RCC8000_IFLAG (IGNBRK|IGNPAR)
-#define RCC8000_OFLAG 0
-#define RCC8000_LFLAG 0
-#define RCC8000_SAMPLES 5
-#define RCC8000_KEEP 3
-
-/*
- * Hopf Radio clock 6021 Format
- *
- */
-#define HOPF6021_ROOTDELAY 0.0
-#define HOPF6021_BASEDELAY 0.0
-#define HOPF6021_DESCRIPTION "HOPF 6021"
-#define HOPF6021_FORMAT "hopf Funkuhr 6021"
-#define HOPF6021_MAXUNSYNC (60*60) /* should be ok for an hour */
-#define HOPF6021_SPEED (B9600)
-#define HOPF6021_CFLAG (CS8|CREAD|CLOCAL)
-#define HOPF6021_IFLAG (IGNBRK|ISTRIP)
-#define HOPF6021_OFLAG 0
-#define HOPF6021_LFLAG 0
-#define HOPF6021_FLAGS 0
-#define HOPF6021_SAMPLES 5
-#define HOPF6021_KEEP 3
-
-/*
- * Diem's Computime Radio Clock Receiver
- */
-#define COMPUTIME_FLAGS 0
-#define COMPUTIME_ROOTDELAY 0.0
-#define COMPUTIME_BASEDELAY 0.0
-#define COMPUTIME_ID DCF_ID
-#define COMPUTIME_DESCRIPTION "Diem's Computime receiver"
-#define COMPUTIME_FORMAT "Diem's Computime Radio Clock"
-#define COMPUTIME_TYPE DCF_TYPE
-#define COMPUTIME_MAXUNSYNC (60*60) /* only trust clock for 1 hour */
-#define COMPUTIME_SPEED (B9600)
-#define COMPUTIME_CFLAG (CSTOPB|CS7|CREAD|CLOCAL)
-#define COMPUTIME_IFLAG (IGNBRK|IGNPAR|ISTRIP)
-#define COMPUTIME_OFLAG 0
-#define COMPUTIME_LFLAG 0
-#define COMPUTIME_SAMPLES 5
-#define COMPUTIME_KEEP 3
-
-/*
- * Varitext Radio Clock Receiver
- */
-#define VARITEXT_FLAGS 0
-#define VARITEXT_ROOTDELAY 0.0
-#define VARITEXT_BASEDELAY 0.0
-#define VARITEXT_ID "MSF"
-#define VARITEXT_DESCRIPTION "Varitext receiver"
-#define VARITEXT_FORMAT "Varitext Radio Clock"
-#define VARITEXT_TYPE DCF_TYPE
-#define VARITEXT_MAXUNSYNC (60*60) /* only trust clock for 1 hour */
-#define VARITEXT_SPEED (B9600)
-#define VARITEXT_CFLAG (CS7|CREAD|CLOCAL|PARENB|PARODD)
-#define VARITEXT_IFLAG (IGNPAR|IGNBRK|INPCK) /*|ISTRIP)*/
-#define VARITEXT_OFLAG 0
-#define VARITEXT_LFLAG 0
-#define VARITEXT_SAMPLES 32
-#define VARITEXT_KEEP 20
-
-static struct parse_clockinfo
-{
- u_long cl_flags; /* operation flags (io modes) */
- void (*cl_poll) P((struct parseunit *)); /* active poll routine */
- int (*cl_init) P((struct parseunit *)); /* active poll init routine */
- void (*cl_event) P((struct parseunit *, int)); /* special event handling (e.g. reset clock) */
- void (*cl_end) P((struct parseunit *)); /* active poll end routine */
- void (*cl_message) P((struct parseunit *, parsetime_t *)); /* process a lower layer message */
- void *cl_data; /* local data area for "poll" mechanism */
- double cl_rootdelay; /* rootdelay */
- double cl_basedelay; /* current offset by which the RS232
- time code is delayed from the actual time */
- const char *cl_id; /* ID code */
- const char *cl_description; /* device name */
- const char *cl_format; /* fixed format */
- u_char cl_type; /* clock type (ntp control) */
- u_long cl_maxunsync; /* time to trust oscillator after losing synch */
- u_long cl_speed; /* terminal input & output baudrate */
- u_long cl_cflag; /* terminal control flags */
- u_long cl_iflag; /* terminal input flags */
- u_long cl_oflag; /* terminal output flags */
- u_long cl_lflag; /* terminal local flags */
- u_long cl_samples; /* samples for median filter */
- u_long cl_keep; /* samples for median filter to keep */
-} parse_clockinfo[] =
-{
- { /* mode 0 */
- MBG_FLAGS,
- NO_POLL,
- NO_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- DCFPZF535_ROOTDELAY,
- DCFPZF535_BASEDELAY,
- DCF_P_ID,
- DCFPZF535_DESCRIPTION,
- DCFPZF535_FORMAT,
- DCF_TYPE,
- DCFPZF535_MAXUNSYNC,
- DCFPZF535_SPEED,
- DCFPZF535_CFLAG,
- DCFPZF535_IFLAG,
- DCFPZF535_OFLAG,
- DCFPZF535_LFLAG,
- DCFPZF535_SAMPLES,
- DCFPZF535_KEEP
- },
- { /* mode 1 */
- MBG_FLAGS,
- NO_POLL,
- NO_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- DCFPZF535OCXO_ROOTDELAY,
- DCFPZF535OCXO_BASEDELAY,
- DCF_P_ID,
- DCFPZF535OCXO_DESCRIPTION,
- DCFPZF535OCXO_FORMAT,
- DCF_TYPE,
- DCFPZF535OCXO_MAXUNSYNC,
- DCFPZF535OCXO_SPEED,
- DCFPZF535OCXO_CFLAG,
- DCFPZF535OCXO_IFLAG,
- DCFPZF535OCXO_OFLAG,
- DCFPZF535OCXO_LFLAG,
- DCFPZF535OCXO_SAMPLES,
- DCFPZF535OCXO_KEEP
- },
- { /* mode 2 */
- MBG_FLAGS,
- NO_POLL,
- NO_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- DCFUA31_ROOTDELAY,
- DCFUA31_BASEDELAY,
- DCF_A_ID,
- DCFUA31_DESCRIPTION,
- DCFUA31_FORMAT,
- DCF_TYPE,
- DCFUA31_MAXUNSYNC,
- DCFUA31_SPEED,
- DCFUA31_CFLAG,
- DCFUA31_IFLAG,
- DCFUA31_OFLAG,
- DCFUA31_LFLAG,
- DCFUA31_SAMPLES,
- DCFUA31_KEEP
- },
- { /* mode 3 */
- MBG_FLAGS,
- NO_POLL,
- NO_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- DCF7000_ROOTDELAY,
- DCF7000_BASEDELAY,
- DCF_A_ID,
- DCF7000_DESCRIPTION,
- DCF7000_FORMAT,
- DCF_TYPE,
- DCF7000_MAXUNSYNC,
- DCF7000_SPEED,
- DCF7000_CFLAG,
- DCF7000_IFLAG,
- DCF7000_OFLAG,
- DCF7000_LFLAG,
- DCF7000_SAMPLES,
- DCF7000_KEEP
- },
- { /* mode 4 */
- NO_CL_FLAGS,
- WSDCF_POLL,
- WSDCF_INIT,
- NO_EVENT,
- WSDCF_END,
- NO_MESSAGE,
- WSDCF_DATA,
- WSDCF_ROOTDELAY,
- WSDCF_BASEDELAY,
- DCF_A_ID,
- WSDCF_DESCRIPTION,
- WSDCF_FORMAT,
- DCF_TYPE,
- WSDCF_MAXUNSYNC,
- WSDCF_SPEED,
- WSDCF_CFLAG,
- WSDCF_IFLAG,
- WSDCF_OFLAG,
- WSDCF_LFLAG,
- WSDCF_SAMPLES,
- WSDCF_KEEP
- },
- { /* mode 5 */
- RAWDCF_FLAGS,
- NO_POLL,
- RAWDCF_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- RAWDCF_ROOTDELAY,
- CONRAD_BASEDELAY,
- DCF_A_ID,
- CONRAD_DESCRIPTION,
- RAWDCF_FORMAT,
- DCF_TYPE,
- RAWDCF_MAXUNSYNC,
- RAWDCF_SPEED,
- RAWDCF_CFLAG,
- RAWDCF_IFLAG,
- RAWDCF_OFLAG,
- RAWDCF_LFLAG,
- RAWDCF_SAMPLES,
- RAWDCF_KEEP
- },
- { /* mode 6 */
- RAWDCF_FLAGS,
- NO_POLL,
- RAWDCF_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- RAWDCF_ROOTDELAY,
- TIMEBRICK_BASEDELAY,
- DCF_A_ID,
- TIMEBRICK_DESCRIPTION,
- RAWDCF_FORMAT,
- DCF_TYPE,
- RAWDCF_MAXUNSYNC,
- RAWDCF_SPEED,
- RAWDCF_CFLAG,
- RAWDCF_IFLAG,
- RAWDCF_OFLAG,
- RAWDCF_LFLAG,
- RAWDCF_SAMPLES,
- RAWDCF_KEEP
- },
- { /* mode 7 */
- MBG_FLAGS,
- GPS16X_POLL,
- GPS16X_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 8 */
- RAWDCF_FLAGS,
- NO_POLL,
- NO_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- RAWDCF_ROOTDELAY,
- IGELCLOCK_BASEDELAY,
- DCF_A_ID,
- IGELCLOCK_DESCRIPTION,
- RAWDCF_FORMAT,
- DCF_TYPE,
- RAWDCF_MAXUNSYNC,
- IGELCLOCK_SPEED,
- IGELCLOCK_CFLAG,
- RAWDCF_IFLAG,
- RAWDCF_OFLAG,
- RAWDCF_LFLAG,
- RAWDCF_SAMPLES,
- RAWDCF_KEEP
- },
- { /* mode 9 */
- TRIMBLETAIP_FLAGS,
-#if TRIM_POLLRATE /* DHD940515: Allow user config */
- NO_POLL,
-#else
- TRIMBLETAIP_POLL,
-#endif
- TRIMBLETAIP_INIT,
- TRIMBLETAIP_EVENT,
- TRIMBLETAIP_END,
- NO_MESSAGE,
- TRIMBLETAIP_DATA,
- TRIMBLETAIP_ROOTDELAY,
- TRIMBLETAIP_BASEDELAY,
- TRIMBLETAIP_ID,
- TRIMBLETAIP_DESCRIPTION,
- TRIMBLETAIP_FORMAT,
- GPS_TYPE,
- TRIMBLETAIP_MAXUNSYNC,
- TRIMBLETAIP_SPEED,
- TRIMBLETAIP_CFLAG,
- TRIMBLETAIP_IFLAG,
- TRIMBLETAIP_OFLAG,
- TRIMBLETAIP_LFLAG,
- TRIMBLETAIP_SAMPLES,
- TRIMBLETAIP_KEEP
- },
- { /* mode 10 */
- TRIMBLETSIP_FLAGS,
-#if TRIM_POLLRATE /* DHD940515: Allow user config */
- NO_POLL,
-#else
- TRIMBLETSIP_POLL,
-#endif
- TRIMBLETSIP_INIT,
- TRIMBLETSIP_EVENT,
- TRIMBLETSIP_END,
- TRIMBLETSIP_MESSAGE,
- TRIMBLETSIP_DATA,
- TRIMBLETSIP_ROOTDELAY,
- TRIMBLETSIP_BASEDELAY,
- TRIMBLETSIP_ID,
- TRIMBLETSIP_DESCRIPTION,
- TRIMBLETSIP_FORMAT,
- GPS_TYPE,
- TRIMBLETSIP_MAXUNSYNC,
- TRIMBLETSIP_SPEED,
- TRIMBLETSIP_CFLAG,
- TRIMBLETSIP_IFLAG,
- TRIMBLETSIP_OFLAG,
- TRIMBLETSIP_LFLAG,
- TRIMBLETSIP_SAMPLES,
- TRIMBLETSIP_KEEP
- },
- { /* mode 11 */
- NO_CL_FLAGS,
- RCC8000_POLL,
- RCC8000_INIT,
- NO_EVENT,
- RCC8000_END,
- NO_MESSAGE,
- RCC8000_DATA,
- RCC8000_ROOTDELAY,
- RCC8000_BASEDELAY,
- RCC8000_ID,
- RCC8000_DESCRIPTION,
- RCC8000_FORMAT,
- DCF_TYPE,
- RCC8000_MAXUNSYNC,
- RCC8000_SPEED,
- RCC8000_CFLAG,
- RCC8000_IFLAG,
- RCC8000_OFLAG,
- RCC8000_LFLAG,
- RCC8000_SAMPLES,
- RCC8000_KEEP
- },
- { /* mode 12 */
- HOPF6021_FLAGS,
- NO_POLL,
- NO_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- HOPF6021_ROOTDELAY,
- HOPF6021_BASEDELAY,
- DCF_ID,
- HOPF6021_DESCRIPTION,
- HOPF6021_FORMAT,
- DCF_TYPE,
- HOPF6021_MAXUNSYNC,
- HOPF6021_SPEED,
- HOPF6021_CFLAG,
- HOPF6021_IFLAG,
- HOPF6021_OFLAG,
- HOPF6021_LFLAG,
- HOPF6021_SAMPLES,
- HOPF6021_KEEP
- },
- { /* mode 13 */
- COMPUTIME_FLAGS,
- NO_POLL,
- NO_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- COMPUTIME_ROOTDELAY,
- COMPUTIME_BASEDELAY,
- COMPUTIME_ID,
- COMPUTIME_DESCRIPTION,
- COMPUTIME_FORMAT,
- COMPUTIME_TYPE,
- COMPUTIME_MAXUNSYNC,
- COMPUTIME_SPEED,
- COMPUTIME_CFLAG,
- COMPUTIME_IFLAG,
- COMPUTIME_OFLAG,
- COMPUTIME_LFLAG,
- COMPUTIME_SAMPLES,
- COMPUTIME_KEEP
- },
- { /* mode 14 */
- RAWDCF_FLAGS,
- NO_POLL,
- RAWDCFDTRSET_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- RAWDCF_ROOTDELAY,
- RAWDCF_BASEDELAY,
- DCF_A_ID,
- RAWDCFDTRSET_DESCRIPTION,
- RAWDCF_FORMAT,
- DCF_TYPE,
- RAWDCF_MAXUNSYNC,
- RAWDCF_SPEED,
- RAWDCF_CFLAG,
- RAWDCF_IFLAG,
- RAWDCF_OFLAG,
- RAWDCF_LFLAG,
- RAWDCF_SAMPLES,
- RAWDCF_KEEP
- },
- { /* mode 15 */
- 0, /* operation flags (io modes) */
- NO_POLL, /* active poll routine */
- NO_INIT, /* active poll init routine */
- 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 */
- 0, /* rootdelay */
- 11.0 /* bits */ / 9600, /* current offset by which the RS232
- time code is delayed from the actual time */
- DCF_ID, /* ID code */
- "WHARTON 400A Series clock", /* device name */
- "WHARTON 400A Series clock Output Format 1", /* fixed format */
- /* Must match a format-name in a libparse/clk_xxx.c file */
- DCF_TYPE, /* clock type (ntp control) */
- (1*60*60), /* time to trust oscillator after losing synch */
- B9600, /* terminal input & output baudrate */
- (CS8|CREAD|PARENB|CLOCAL|HUPCL),/* terminal control flags */
- 0, /* terminal input flags */
- 0, /* terminal output flags */
- 0, /* terminal local flags */
- 5, /* samples for median filter */
- 3, /* samples for median filter to keep */
- },
- { /* mode 16 - RAWDCF RTS set, DTR clr */
- RAWDCF_FLAGS,
- NO_POLL,
- RAWDCFDTRCLRRTSSET_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- RAWDCF_ROOTDELAY,
- RAWDCF_BASEDELAY,
- DCF_A_ID,
- RAWDCFDTRCLRRTSSET_DESCRIPTION,
- RAWDCF_FORMAT,
- DCF_TYPE,
- RAWDCF_MAXUNSYNC,
- RAWDCF_SPEED,
- RAWDCF_CFLAG,
- RAWDCF_IFLAG,
- RAWDCF_OFLAG,
- RAWDCF_LFLAG,
- RAWDCF_SAMPLES,
- RAWDCF_KEEP
- },
- { /* mode 17 */
- VARITEXT_FLAGS,
- NO_POLL,
- NO_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_DATA,
- VARITEXT_ROOTDELAY,
- VARITEXT_BASEDELAY,
- VARITEXT_ID,
- VARITEXT_DESCRIPTION,
- VARITEXT_FORMAT,
- VARITEXT_TYPE,
- VARITEXT_MAXUNSYNC,
- VARITEXT_SPEED,
- VARITEXT_CFLAG,
- VARITEXT_IFLAG,
- VARITEXT_OFLAG,
- VARITEXT_LFLAG,
- VARITEXT_SAMPLES,
- VARITEXT_KEEP
- }
-};
-
-static int ncltypes = sizeof(parse_clockinfo) / sizeof(struct parse_clockinfo);
-
-#define CLK_REALTYPE(x) ((int)(((x)->ttl) & 0x7F))
-#define CLK_TYPE(x) ((CLK_REALTYPE(x) >= ncltypes) ? ~0 : CLK_REALTYPE(x))
-#define CLK_UNIT(x) ((int)REFCLOCKUNIT(&(x)->srcadr))
-#define CLK_PPS(x) (((x)->ttl) & 0x80)
-
-/*
- * Other constant stuff
- */
-#define PARSEHSREFID 0x7f7f08ff /* 127.127.8.255 refid for hi strata */
-
-#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])
-
-static void parse_event P((struct parseunit *, int));
-static void parse_process P((struct parseunit *, parsetime_t *));
-static void clear_err P((struct parseunit *, u_long));
-static int list_err P((struct parseunit *, u_long));
-static char * l_mktime P((u_long));
-
-/**===========================================================================
- ** implementation error message regression module
- **/
-static void
-clear_err(
- struct parseunit *parse,
- u_long lstate
- )
-{
- if (lstate == ERR_ALL)
- {
- int i;
-
- for (i = 0; i < ERR_CNT; i++)
- {
- parse->errors[i].err_stage = err_tbl[i];
- parse->errors[i].err_cnt = 0;
- parse->errors[i].err_last = 0;
- parse->errors[i].err_started = 0;
- parse->errors[i].err_suppressed = 0;
- }
- }
- else
- {
- parse->errors[lstate].err_stage = err_tbl[lstate];
- parse->errors[lstate].err_cnt = 0;
- parse->errors[lstate].err_last = 0;
- parse->errors[lstate].err_started = 0;
- parse->errors[lstate].err_suppressed = 0;
- }
-}
-
-static int
-list_err(
- struct parseunit *parse,
- u_long lstate
- )
-{
- int do_it;
- struct errorinfo *err = &parse->errors[lstate];
-
- if (err->err_started == 0)
- {
- err->err_started = current_time;
- }
-
- do_it = (current_time - err->err_last) >= err->err_stage->err_delay;
-
- if (do_it)
- err->err_cnt++;
-
- if (err->err_stage->err_count &&
- (err->err_cnt >= err->err_stage->err_count))
- {
- err->err_stage++;
- err->err_cnt = 0;
- }
-
- if (!err->err_cnt && do_it)
- msyslog(LOG_INFO, "PARSE receiver #%d: interval for following error message class is at least %s",
- CLK_UNIT(parse->peer), l_mktime(err->err_stage->err_delay));
-
- if (!do_it)
- err->err_suppressed++;
- else
- err->err_last = current_time;
-
- if (do_it && err->err_suppressed)
- {
- msyslog(LOG_INFO, "PARSE receiver #%d: %ld message%s suppressed, error condition class persists for %s",
- CLK_UNIT(parse->peer), err->err_suppressed, (err->err_suppressed == 1) ? " was" : "s where",
- l_mktime(current_time - err->err_started));
- err->err_suppressed = 0;
- }
-
- return do_it;
-}
-
-/*--------------------------------------------------
- * mkreadable - make a printable ascii string (without
- * embedded quotes so that the ntpq protocol isn't
- * fooled
- */
-#ifndef isprint
-#define isprint(_X_) (((_X_) > 0x1F) && ((_X_) < 0x7F))
-#endif
-
-static char *
-mkreadable(
- char *buffer,
- long blen,
- const char *src,
- u_long srclen,
- int hex
- )
-{
- char *b = buffer;
- char *endb = (char *)0;
-
- if (blen < 4)
- return (char *)0; /* don't bother with mini buffers */
-
- endb = buffer + blen - 4;
-
- blen--; /* account for '\0' */
-
- while (blen && srclen--)
- {
- if (!hex && /* no binary only */
- (*src != '\\') && /* no plain \ */
- (*src != '"') && /* no " */
- isprint((int)*src)) /* only printables */
- { /* they are easy... */
- *buffer++ = *src++;
- blen--;
- }
- else
- {
- if (blen < 4)
- {
- while (blen--)
- {
- *buffer++ = '.';
- }
- *buffer = '\0';
- return b;
- }
- else
- {
- if (*src == '\\')
- {
- strcpy(buffer,"\\\\");
- buffer += 2;
- blen -= 2;
- src++;
- }
- else
- {
- sprintf(buffer, "\\x%02x", *src++);
- blen -= 4;
- buffer += 4;
- }
- }
- }
- if (srclen && !blen && endb) /* overflow - set last chars to ... */
- strcpy(endb, "...");
- }
-
- *buffer = '\0';
- return b;
-}
-
-
-/*--------------------------------------------------
- * mkascii - make a printable ascii string
- * assumes (unless defined better) 7-bit ASCII
- */
-static char *
-mkascii(
- char *buffer,
- long blen,
- const char *src,
- u_long srclen
- )
-{
- return mkreadable(buffer, blen, src, srclen, 0);
-}
-
-/**===========================================================================
- ** implementation of i/o handling methods
- ** (all STREAM, partial STREAM, user level)
- **/
-
-/*
- * define possible io handling methods
- */
-#ifdef STREAM
-static int ppsclock_init P((struct parseunit *));
-static int stream_init P((struct parseunit *));
-static void stream_end P((struct parseunit *));
-static int stream_enable P((struct parseunit *));
-static int stream_disable P((struct parseunit *));
-static int stream_setcs P((struct parseunit *, parsectl_t *));
-static int stream_getfmt P((struct parseunit *, parsectl_t *));
-static int stream_setfmt P((struct parseunit *, parsectl_t *));
-static int stream_timecode P((struct parseunit *, parsectl_t *));
-static void stream_receive P((struct recvbuf *));
-#endif
-
-static int local_init P((struct parseunit *));
-static void local_end P((struct parseunit *));
-static int local_nop P((struct parseunit *));
-static int local_setcs P((struct parseunit *, parsectl_t *));
-static int local_getfmt P((struct parseunit *, parsectl_t *));
-static int local_setfmt P((struct parseunit *, parsectl_t *));
-static int local_timecode P((struct parseunit *, parsectl_t *));
-static void local_receive P((struct recvbuf *));
-static int local_input P((struct recvbuf *));
-
-static bind_t io_bindings[] =
-{
-#ifdef STREAM
- {
- "parse STREAM",
- stream_init,
- stream_end,
- stream_setcs,
- stream_disable,
- stream_enable,
- stream_getfmt,
- stream_setfmt,
- stream_timecode,
- stream_receive,
- 0,
- },
- {
- "ppsclock STREAM",
- ppsclock_init,
- local_end,
- local_setcs,
- local_nop,
- local_nop,
- local_getfmt,
- local_setfmt,
- local_timecode,
- local_receive,
- local_input,
- },
-#endif
- {
- "normal",
- local_init,
- local_end,
- local_setcs,
- local_nop,
- local_nop,
- local_getfmt,
- local_setfmt,
- local_timecode,
- local_receive,
- local_input,
- },
- {
- (char *)0,
- }
-};
-
-#ifdef STREAM
-
-#define fix_ts(_X_) \
- if ((&(_X_))->tv.tv_usec >= 1000000) \
- { \
- (&(_X_))->tv.tv_usec -= 1000000; \
- (&(_X_))->tv.tv_sec += 1; \
- }
-
-#define cvt_ts(_X_, _Y_) \
- { \
- l_fp ts; \
- fix_ts((_X_)); \
- if (!buftvtots((const char *)&(&(_X_))->tv, &ts)) \
- { \
- ERR(ERR_BADDATA) \
- msyslog(LOG_ERR,"parse: stream_receive: timestamp conversion error (buftvtots) (%s) (%ld.%06ld) ", (_Y_), (long)(&(_X_))->tv.tv_sec, (long)(&(_X_))->tv.tv_usec);\
- return; \
- } \
- else \
- { \
- (&(_X_))->fp = ts; \
- } \
- }
-
-/*--------------------------------------------------
- * ppsclock STREAM init
- */
-static int
-ppsclock_init(
- struct parseunit *parse
- )
-{
- static char m1[] = "ppsclocd";
- static char m2[] = "ppsclock";
-
- /*
- * 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 (errno != EINVAL)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: ppsclock_init: ioctl(fd, I_PUSH, \"ppsclock\"): %m",
- CLK_UNIT(parse->peer));
- }
- return 0;
- }
- if (!local_init(parse))
- {
- (void)ioctl(parse->generic->io.fd, I_POP, (caddr_t)0);
- return 0;
- }
-
- parse->flags |= PARSE_PPSCLOCK;
- return 1;
-}
-
-/*--------------------------------------------------
- * parse STREAM init
- */
-static int
-stream_init(
- struct parseunit *parse
- )
-{
- static char m1[] = "parse";
- /*
- * now push the parse streams module
- * to test whether it is there (neat interface 8-( )
- */
- if (ioctl(parse->generic->io.fd, I_PUSH, (caddr_t)m1) == -1)
- {
- if (errno != EINVAL) /* accept non-existence */
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: stream_init: ioctl(fd, I_PUSH, \"parse\"): %m", CLK_UNIT(parse->peer));
- }
- return 0;
- }
- else
- {
- while(ioctl(parse->generic->io.fd, I_POP, (caddr_t)0) == 0)
- /* empty loop */;
-
- /*
- * now push it a second time after we have removed all
- * module garbage
- */
- if (ioctl(parse->generic->io.fd, I_PUSH, (caddr_t)m1) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: stream_init: ioctl(fd, I_PUSH, \"parse\"): %m", CLK_UNIT(parse->peer));
- return 0;
- }
- else
- {
- return 1;
- }
- }
-}
-
-/*--------------------------------------------------
- * parse STREAM end
- */
-static void
-stream_end(
- struct parseunit *parse
- )
-{
- while(ioctl(parse->generic->io.fd, I_POP, (caddr_t)0) == 0)
- /* empty loop */;
-}
-
-/*--------------------------------------------------
- * STREAM setcs
- */
-static int
-stream_setcs(
- struct parseunit *parse,
- parsectl_t *tcl
- )
-{
- struct strioctl strioc;
-
- strioc.ic_cmd = PARSEIOC_SETCS;
- strioc.ic_timout = 0;
- strioc.ic_dp = (char *)tcl;
- strioc.ic_len = sizeof (*tcl);
-
- if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: stream_setcs: ioctl(fd, I_STR, PARSEIOC_SETCS): %m", CLK_UNIT(parse->peer));
- return 0;
- }
- return 1;
-}
-
-/*--------------------------------------------------
- * STREAM enable
- */
-static int
-stream_enable(
- struct parseunit *parse
- )
-{
- struct strioctl strioc;
-
- strioc.ic_cmd = PARSEIOC_ENABLE;
- strioc.ic_timout = 0;
- strioc.ic_dp = (char *)0;
- strioc.ic_len = 0;
-
- if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: stream_enable: ioctl(fd, I_STR, PARSEIOC_ENABLE): %m", CLK_UNIT(parse->peer));
- return 0;
- }
- parse->generic->io.clock_recv = stream_receive; /* ok - parse input in kernel */
- return 1;
-}
-
-/*--------------------------------------------------
- * STREAM disable
- */
-static int
-stream_disable(
- struct parseunit *parse
- )
-{
- struct strioctl strioc;
-
- strioc.ic_cmd = PARSEIOC_DISABLE;
- strioc.ic_timout = 0;
- strioc.ic_dp = (char *)0;
- strioc.ic_len = 0;
-
- if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: stream_disable: ioctl(fd, I_STR, PARSEIOC_DISABLE): %m", CLK_UNIT(parse->peer));
- return 0;
- }
- parse->generic->io.clock_recv = local_receive; /* ok - parse input in daemon */
- return 1;
-}
-
-/*--------------------------------------------------
- * STREAM getfmt
- */
-static int
-stream_getfmt(
- struct parseunit *parse,
- parsectl_t *tcl
- )
-{
- struct strioctl strioc;
-
- strioc.ic_cmd = PARSEIOC_GETFMT;
- strioc.ic_timout = 0;
- strioc.ic_dp = (char *)tcl;
- strioc.ic_len = sizeof (*tcl);
- if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: ioctl(fd, I_STR, PARSEIOC_GETFMT): %m", CLK_UNIT(parse->peer));
- return 0;
- }
- return 1;
-}
-
-/*--------------------------------------------------
- * STREAM setfmt
- */
-static int
-stream_setfmt(
- struct parseunit *parse,
- parsectl_t *tcl
- )
-{
- struct strioctl strioc;
-
- strioc.ic_cmd = PARSEIOC_SETFMT;
- strioc.ic_timout = 0;
- strioc.ic_dp = (char *)tcl;
- strioc.ic_len = sizeof (*tcl);
-
- if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: stream_setfmt: ioctl(fd, I_STR, PARSEIOC_SETFMT): %m", CLK_UNIT(parse->peer));
- return 0;
- }
- return 1;
-}
-
-
-/*--------------------------------------------------
- * STREAM timecode
- */
-static int
-stream_timecode(
- struct parseunit *parse,
- parsectl_t *tcl
- )
-{
- struct strioctl strioc;
-
- strioc.ic_cmd = PARSEIOC_TIMECODE;
- strioc.ic_timout = 0;
- strioc.ic_dp = (char *)tcl;
- strioc.ic_len = sizeof (*tcl);
-
- if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
- {
- ERR(ERR_INTERNAL)
- msyslog(LOG_ERR, "PARSE receiver #%d: stream_timecode: ioctl(fd, I_STR, PARSEIOC_TIMECODE): %m", CLK_UNIT(parse->peer));
- return 0;
- }
- clear_err(parse, ERR_INTERNAL);
- return 1;
-}
-
-/*--------------------------------------------------
- * STREAM receive
- */
-static void
-stream_receive(
- struct recvbuf *rbufp
- )
-{
- struct parseunit *parse = (struct parseunit *)((void *)rbufp->recv_srcclock);
- parsetime_t parsetime;
-
- if (!parse->peer)
- return;
-
- if (rbufp->recv_length != sizeof(parsetime_t))
- {
- 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;
- }
- clear_err(parse, ERR_BADIO);
-
- memmove((caddr_t)&parsetime,
- (caddr_t)rbufp->recv_buffer,
- sizeof(parsetime_t));
-
-#ifdef DEBUG
- if (debug > 3)
- {
- printf("PARSE receiver #%d: status %06x, state %08x, time %lx.%08lx, stime %lx.%08lx, ptime %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);
- }
-#endif
-
- /*
- * switch time stamp world - be sure to normalize small usec field
- * errors.
- */
-
- cvt_ts(parsetime.parse_stime, "parse_stime");
-
- if (PARSE_TIMECODE(parsetime.parse_state))
- {
- cvt_ts(parsetime.parse_time, "parse_time");
- }
-
- if (PARSE_PPS(parsetime.parse_state))
- cvt_ts(parsetime.parse_ptime, "parse_ptime");
-
- parse_process(parse, &parsetime);
-}
-#endif
-
-/*--------------------------------------------------
- * local init
- */
-static int
-local_init(
- struct parseunit *parse
- )
-{
- return parse_ioinit(&parse->parseio);
-}
-
-/*--------------------------------------------------
- * local end
- */
-static void
-local_end(
- struct parseunit *parse
- )
-{
- parse_ioend(&parse->parseio);
-}
-
-
-/*--------------------------------------------------
- * local nop
- */
-static int
-local_nop(
- struct parseunit *parse
- )
-{
- return 1;
-}
-
-/*--------------------------------------------------
- * local setcs
- */
-static int
-local_setcs(
- struct parseunit *parse,
- parsectl_t *tcl
- )
-{
- return parse_setcs(tcl, &parse->parseio);
-}
-
-/*--------------------------------------------------
- * local getfmt
- */
-static int
-local_getfmt(
- struct parseunit *parse,
- parsectl_t *tcl
- )
-{
- return parse_getfmt(tcl, &parse->parseio);
-}
-
-/*--------------------------------------------------
- * local setfmt
- */
-static int
-local_setfmt(
- struct parseunit *parse,
- parsectl_t *tcl
- )
-{
- return parse_setfmt(tcl, &parse->parseio);
-}
-
-/*--------------------------------------------------
- * local timecode
- */
-static int
-local_timecode(
- struct parseunit *parse,
- parsectl_t *tcl
- )
-{
- return parse_timecode(tcl, &parse->parseio);
-}
-
-
-/*--------------------------------------------------
- * local input
- */
-static int
-local_input(
- struct recvbuf *rbufp
- )
-{
- struct parseunit *parse = (struct parseunit *)((void *)rbufp->recv_srcclock);
- int count;
- unsigned char *s;
- timestamp_t ts;
-
- if (!parse->peer)
- return 0;
-
- /*
- * eat all characters, parsing then and feeding complete samples
- */
- count = rbufp->recv_length;
- s = (unsigned char *)rbufp->recv_buffer;
- ts.fp = rbufp->recv_time;
-
- while (count--)
- {
- if (parse_ioread(&parse->parseio, (unsigned int)(*s++), &ts))
- {
- struct recvbuf buf;
-
- /*
- * got something good to eat
- */
- if (!PARSE_PPS(parse->parseio.parse_dtime.parse_state))
- {
-#ifdef TIOCDCDTIMESTAMP
- struct timeval dcd_time;
-
- if (ioctl(rbufp->fd, TIOCDCDTIMESTAMP, &dcd_time) != -1)
- {
- l_fp tstmp;
-
- TVTOTS(&dcd_time, &tstmp);
- tstmp.l_ui += JAN_1970;
- L_SUB(&ts.fp, &tstmp);
- if (ts.fp.l_ui == 0)
- {
-#ifdef DEBUG
- if (debug)
- {
- printf(
- "parse: local_receive: fd %d DCDTIMESTAMP %s\n",
- rbufp->fd,
- lfptoa(&tstmp, 6));
- printf(" sigio %s\n",
- lfptoa(&ts.fp, 6));
- }
-#endif
- parse->parseio.parse_dtime.parse_ptime.fp = tstmp;
- parse->parseio.parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
- }
- }
-#else /* TIOCDCDTIMESTAMP */
-#if defined(HAVE_STRUCT_PPSCLOCKEV) && (defined(HAVE_CIOGETEV) || defined(HAVE_TIOCGPPSEV))
- if (parse->flags & PARSE_PPSCLOCK)
- {
- l_fp tts;
- struct ppsclockev ev;
-
-#ifdef HAVE_CIOGETEV
- if (ioctl(parse->generic->io.fd, CIOGETEV, (caddr_t)&ev) == 0)
-#endif
-#ifdef HAVE_TIOCGPPSEV
- if (ioctl(parse->generic->io.fd, TIOCGPPSEV, (caddr_t)&ev) == 0)
-#endif
- {
- 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))
- {
- 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;
- }
- }
-#endif
-#endif /* TIOCDCDTIMESTAMP */
- }
- if (count)
- { /* simulate receive */
- memmove((caddr_t)buf.recv_buffer,
- (caddr_t)&parse->parseio.parse_dtime,
- sizeof(parsetime_t));
- 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
- {
- memmove((caddr_t)rbufp->recv_buffer,
- (caddr_t)&parse->parseio.parse_dtime,
- sizeof(parsetime_t));
- parse_iodone(&parse->parseio);
- rbufp->recv_length = sizeof(parsetime_t);
- return 1; /* got something & in place return */
- }
- }
- }
- return 0; /* nothing to pass up */
-}
-
-/*--------------------------------------------------
- * local receive
- */
-static void
-local_receive(
- struct recvbuf *rbufp
- )
-{
- struct parseunit *parse = (struct parseunit *)((void *)rbufp->recv_srcclock);
- parsetime_t parsetime;
-
- if (!parse->peer)
- return;
-
- if (rbufp->recv_length != sizeof(parsetime_t))
- {
- 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;
- }
- clear_err(parse, ERR_BADIO);
-
- memmove((caddr_t)&parsetime,
- (caddr_t)rbufp->recv_buffer,
- sizeof(parsetime_t));
-
-#ifdef DEBUG
- if (debug > 3)
- {
- printf("PARSE receiver #%d: status %06x, state %08x, time %lx.%08lx, stime %lx.%08lx, ptime %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);
- }
-#endif
-
- parse_process(parse, &parsetime);
-}
-
-/*--------------------------------------------------
- * init_iobinding - find and initialize lower layers
- */
-static bind_t *
-init_iobinding(
- struct parseunit *parse
- )
-{
- bind_t *b = io_bindings;
-
- while (b->bd_description != (char *)0)
- {
- if ((*b->bd_init)(parse))
- {
- return b;
- }
- b++;
- }
- return (bind_t *)0;
-}
-
-/**===========================================================================
- ** support routines
- **/
-
-/*--------------------------------------------------
- * convert a flag field to a string
- */
-static char *
-parsestate(
- u_long lstate,
- char *buffer
- )
-{
- static struct bits
- {
- u_long bit;
- const char *name;
- } flagstrings[] =
- {
- { PARSEB_ANNOUNCE, "DST SWITCH WARNING" },
- { PARSEB_POWERUP, "NOT SYNCHRONIZED" },
- { PARSEB_NOSYNC, "TIME CODE NOT CONFIRMED" },
- { PARSEB_DST, "DST" },
- { PARSEB_UTC, "UTC DISPLAY" },
- { PARSEB_LEAPADD, "LEAP ADD WARNING" },
- { PARSEB_LEAPDEL, "LEAP DELETE WARNING" },
- { PARSEB_LEAPSECOND, "LEAP SECOND" },
- { PARSEB_ALTERNATE, "ALTERNATE ANTENNA" },
- { PARSEB_TIMECODE, "TIME CODE" },
- { PARSEB_PPS, "PPS" },
- { PARSEB_POSITION, "POSITION" },
- { 0 }
- };
-
- static struct sbits
- {
- u_long bit;
- const char *name;
- } sflagstrings[] =
- {
- { PARSEB_S_LEAP, "LEAP INDICATION" },
- { PARSEB_S_PPS, "PPS SIGNAL" },
- { PARSEB_S_ANTENNA, "ANTENNA" },
- { PARSEB_S_POSITION, "POSITION" },
- { 0 }
- };
- int i;
-
- *buffer = '\0';
-
- i = 0;
- while (flagstrings[i].bit)
- {
- if (flagstrings[i].bit & lstate)
- {
- if (buffer[0])
- strcat(buffer, "; ");
- strcat(buffer, flagstrings[i].name);
- }
- i++;
- }
-
- if (lstate & (PARSEB_S_LEAP|PARSEB_S_ANTENNA|PARSEB_S_PPS|PARSEB_S_POSITION))
- {
- char *s, *t;
-
- if (buffer[0])
- strcat(buffer, "; ");
-
- strcat(buffer, "(");
-
- t = s = buffer + strlen(buffer);
-
- i = 0;
- while (sflagstrings[i].bit)
- {
- if (sflagstrings[i].bit & lstate)
- {
- if (t != s)
- {
- strcpy(t, "; ");
- t += 2;
- }
-
- strcpy(t, sflagstrings[i].name);
- t += strlen(t);
- }
- i++;
- }
- strcpy(t, ")");
- }
- return buffer;
-}
-
-/*--------------------------------------------------
- * convert a status flag field to a string
- */
-static char *
-parsestatus(
- u_long lstate,
- char *buffer
- )
-{
- static struct bits
- {
- u_long bit;
- const char *name;
- } flagstrings[] =
- {
- { CVT_OK, "CONVERSION SUCCESSFUL" },
- { CVT_NONE, "NO CONVERSION" },
- { CVT_FAIL, "CONVERSION FAILED" },
- { CVT_BADFMT, "ILLEGAL FORMAT" },
- { CVT_BADDATE, "DATE ILLEGAL" },
- { CVT_BADTIME, "TIME ILLEGAL" },
- { CVT_ADDITIONAL, "ADDITIONAL DATA" },
- { 0 }
- };
- int i;
-
- *buffer = '\0';
-
- i = 0;
- while (flagstrings[i].bit)
- {
- if (flagstrings[i].bit & lstate)
- {
- if (buffer[0])
- strcat(buffer, "; ");
- strcat(buffer, flagstrings[i].name);
- }
- i++;
- }
-
- return buffer;
-}
-
-/*--------------------------------------------------
- * convert a clock status flag field to a string
- */
-static const char *
-clockstatus(
- u_long lstate
- )
-{
- static char buffer[20];
- static struct status
- {
- u_long value;
- const char *name;
- } flagstrings[] =
- {
- { CEVNT_NOMINAL, "NOMINAL" },
- { CEVNT_TIMEOUT, "NO RESPONSE" },
- { CEVNT_BADREPLY,"BAD FORMAT" },
- { CEVNT_FAULT, "FAULT" },
- { CEVNT_PROP, "PROPAGATION DELAY" },
- { CEVNT_BADDATE, "ILLEGAL DATE" },
- { CEVNT_BADTIME, "ILLEGAL TIME" },
- { (unsigned)~0L }
- };
- int i;
-
- i = 0;
- while (flagstrings[i].value != ~0)
- {
- if (flagstrings[i].value == lstate)
- {
- return flagstrings[i].name;
- }
- i++;
- }
-
- sprintf(buffer, "unknown #%ld", (u_long)lstate);
-
- return buffer;
-}
-
-
-/*--------------------------------------------------
- * l_mktime - make representation of a relative time
- */
-static char *
-l_mktime(
- u_long delta
- )
-{
- u_long tmp, m, s;
- static char buffer[40];
-
- buffer[0] = '\0';
-
- if ((tmp = delta / (60*60*24)) != 0)
- {
- sprintf(buffer, "%ldd+", (u_long)tmp);
- delta -= tmp * 60*60*24;
- }
-
- s = delta % 60;
- delta /= 60;
- m = delta % 60;
- delta /= 60;
-
- sprintf(buffer+strlen(buffer), "%02d:%02d:%02d",
- (int)delta, (int)m, (int)s);
-
- return buffer;
-}
-
-
-/*--------------------------------------------------
- * parse_statistics - list summary of clock states
- */
-static void
-parse_statistics(
- struct parseunit *parse
- )
-{
- int i;
-
- NLOG(NLOG_CLOCKSTATIST) /* conditional if clause for conditional syslog */
- {
- msyslog(LOG_INFO, "PARSE receiver #%d: running time: %s",
- CLK_UNIT(parse->peer),
- l_mktime(current_time - parse->generic->timestarted));
-
- msyslog(LOG_INFO, "PARSE receiver #%d: current status: %s",
- CLK_UNIT(parse->peer),
- clockstatus(parse->generic->currentstatus));
-
- for (i = 0; i <= CEVNT_MAX; i++)
- {
- u_long s_time;
- u_long percent, d = current_time - parse->generic->timestarted;
-
- percent = s_time = PARSE_STATETIME(parse, i);
-
- while (((u_long)(~0) / 10000) < percent)
- {
- percent /= 10;
- d /= 10;
- }
-
- if (d)
- percent = (percent * 10000) / d;
- else
- percent = 10000;
-
- if (s_time)
- msyslog(LOG_INFO, "PARSE receiver #%d: state %18s: %13s (%3ld.%02ld%%)",
- CLK_UNIT(parse->peer),
- clockstatus((unsigned int)i),
- l_mktime(s_time),
- percent / 100, percent % 100);
- }
- }
-}
-
-/*--------------------------------------------------
- * cparse_statistics - wrapper for statistics call
- */
-static void
-cparse_statistics(
- register struct parseunit *parse
- )
-{
- if (parse->laststatistic + PARSESTATISTICS < current_time)
- parse_statistics(parse);
- parse->laststatistic = current_time;
-}
-
-/**===========================================================================
- ** ntp interface routines
- **/
-
-/*--------------------------------------------------
- * 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
-parse_shutdown(
- int unit,
- struct peer *peer
- )
-{
- struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr;
-
- if (parse && !parse->peer)
- {
- msyslog(LOG_ERR,
- "PARSE receiver #%d: parse_shutdown: INTERNAL ERROR, unit not in use", unit);
- return;
- }
-
- /*
- * print statistics a last time and
- * stop statistics machine
- */
- parse_statistics(parse);
-
- if (parse->parse_type->cl_end)
- {
- parse->parse_type->cl_end(parse);
- }
-
- if (parse->binding)
- PARSE_END(parse);
-
- /*
- * Tell the I/O module to turn us off. We're history.
- */
- io_closeclock(&parse->generic->io);
-
- free_varlist(parse->kv);
-
- NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
- msyslog(LOG_INFO, "PARSE receiver #%d: reference clock \"%s\" removed",
- CLK_UNIT(parse->peer), parse->parse_type->cl_description);
-
- parse->peer = (struct peer *)0; /* unused now */
- free(parse);
-}
-
-/*--------------------------------------------------
- * parse_start - open the PARSE devices and initialize data for processing
- */
-static int
-parse_start(
- int sysunit,
- struct peer *peer
- )
-{
- u_int unit;
- int fd232;
-#ifdef HAVE_TERMIOS
- struct termios tio; /* NEEDED FOR A LONG TIME ! */
-#endif
-#ifdef HAVE_SYSV_TTYS
- struct termio tio; /* NEEDED FOR A LONG TIME ! */
-#endif
- struct parseunit * parse;
- char parsedev[sizeof(PARSEDEVICE)+20];
- parsectl_t tmp_ctl;
- u_int type;
-
- type = CLK_TYPE(peer);
- unit = CLK_UNIT(peer);
-
- if ((type == ~0) || (parse_clockinfo[type].cl_description == (char *)0))
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: unsupported clock type %d (max %d)",
- unit, CLK_REALTYPE(peer), ncltypes-1);
- return 0;
- }
-
- /*
- * Unit okay, attempt to open the device.
- */
- (void) sprintf(parsedev, PARSEDEVICE, unit);
-
-#ifndef O_NOCTTY
-#define O_NOCTTY 0
-#endif
-
- fd232 = open(parsedev, O_RDWR | O_NOCTTY
-#ifdef O_NONBLOCK
- | O_NONBLOCK
-#endif
- , 0777);
-
- if (fd232 == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: open of %s failed: %m", unit, parsedev);
- return 0;
- }
-
- parse = (struct parseunit *)emalloc(sizeof(struct parseunit));
-
- memset((char *)parse, 0, sizeof(struct parseunit));
-
- parse->generic = peer->procptr; /* link up */
- parse->generic->unitptr = (caddr_t)parse; /* link down */
-
- /*
- * Set up the structures
- */
- 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->lastmissed = 0; /* assume got everything */
- parse->ppsserial = 0;
- parse->localdata = (void *)0;
- parse->localstate = 0;
- parse->kv = (struct ctl_var *)0;
-
- clear_err(parse, ERR_ALL);
-
- parse->parse_type = &parse_clockinfo[type];
-
- parse->generic->fudgetime1 = parse->parse_type->cl_basedelay;
-
- parse->generic->fudgetime2 = 0.0;
-
- 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
- parse->generic->refid = htonl(PARSEHSREFID);
-
- parse->generic->io.fd = fd232;
-
- parse->peer = peer; /* marks it also as busy */
-
- /*
- * configure terminal line
- */
- if (TTY_GETATTR(fd232, &tio) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: tcgetattr(%d, &tio): %m", unit, fd232);
- parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
- return 0;
- }
- else
- {
-#ifndef _PC_VDISABLE
- memset((char *)tio.c_cc, 0, sizeof(tio.c_cc));
-#else
- int disablec;
- errno = 0; /* pathconf can deliver -1 without changing errno ! */
-
- disablec = fpathconf(parse->generic->io.fd, _PC_VDISABLE);
- if (disablec == -1 && errno)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: fpathconf(fd, _PC_VDISABLE): %m", CLK_UNIT(parse->peer));
- memset((char *)tio.c_cc, 0, sizeof(tio.c_cc)); /* best guess */
- }
- else
- if (disablec != -1)
- memset((char *)tio.c_cc, disablec, sizeof(tio.c_cc));
-#endif
-
-#if defined (VMIN) || defined(VTIME)
- if ((parse_clockinfo[type].cl_lflag & ICANON) == 0)
- {
-#ifdef VMIN
- tio.c_cc[VMIN] = 1;
-#endif
-#ifdef VTIME
- tio.c_cc[VTIME] = 0;
-#endif
- }
-#endif
-
- tio.c_cflag = parse_clockinfo[type].cl_cflag;
- tio.c_iflag = parse_clockinfo[type].cl_iflag;
- tio.c_oflag = parse_clockinfo[type].cl_oflag;
- tio.c_lflag = parse_clockinfo[type].cl_lflag;
-
-
-#ifdef HAVE_TERMIOS
- if ((cfsetospeed(&tio, parse_clockinfo[type].cl_speed) == -1) ||
- (cfsetispeed(&tio, parse_clockinfo[type].cl_speed) == -1))
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: tcset{i,o}speed(&tio, speed): %m", unit);
- parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
- return 0;
- }
-#else
- tio.c_cflag |= parse_clockinfo[type].cl_speed;
-#endif
-
-#if defined(HAVE_TIO_SERIAL_STUFF) /* Linux hack: define PPS interface */
- {
- struct serial_struct ss;
- if (ioctl(fd232, TIOCGSERIAL, &ss) < 0 ||
- (
-#ifdef ASYNC_LOW_LATENCY
- ss.flags |= ASYNC_LOW_LATENCY,
-#endif
-#ifdef ASYNC_PPS_CD_NEG
- ss.flags |= ASYNC_PPS_CD_NEG,
-#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
-#ifdef HAVE_TIOCSPPS /* SUN PPS support */
- if (CLK_PPS(parse->peer))
- {
- int i = 1;
-
- if (ioctl(fd232, TIOCSPPS, (caddr_t)&i) == 0)
- {
- parse->flags |= PARSE_PPSCLOCK;
- }
- }
-#endif
-
- if (TTY_SETATTR(fd232, &tio) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: tcsetattr(%d, &tio): %m", unit, fd232);
- parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
- return 0;
- }
- }
-
- /*
- * Insert in async io device list.
- */
- 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)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: io sub system initialisation failed.", CLK_UNIT(parse->peer));
- parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
- return 0; /* well, ok - special initialisation broke */
- }
-
- /*
- * as we always(?) get 8 bit chars we want to be
- * sure, that the upper bits are zero for less
- * than 8 bit I/O - so we pass that information on.
- * note that there can be only one bit count format
- * per file descriptor
- */
-
- switch (tio.c_cflag & CSIZE)
- {
- case CS5:
- tmp_ctl.parsesetcs.parse_cs = PARSE_IO_CS5;
- break;
-
- case CS6:
- tmp_ctl.parsesetcs.parse_cs = PARSE_IO_CS6;
- break;
-
- case CS7:
- tmp_ctl.parsesetcs.parse_cs = PARSE_IO_CS7;
- break;
-
- case CS8:
- tmp_ctl.parsesetcs.parse_cs = PARSE_IO_CS8;
- break;
- }
-
- if (!PARSE_SETCS(parse, &tmp_ctl))
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: parse_setcs() FAILED.", unit);
- parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
- return 0; /* well, ok - special initialisation broke */
- }
-
- strcpy(tmp_ctl.parseformat.parse_buffer, parse->parse_type->cl_format);
- tmp_ctl.parseformat.parse_count = strlen(tmp_ctl.parseformat.parse_buffer);
-
- if (!PARSE_SETFMT(parse, &tmp_ctl))
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: parse_setfmt() FAILED.", unit);
- parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
- return 0; /* well, ok - special initialisation broke */
- }
-
- /*
- * get rid of all IO accumulated so far
- */
-#ifdef HAVE_TERMIOS
- (void) tcflush(parse->generic->io.fd, TCIOFLUSH);
-#else
-#ifdef TCFLSH
- {
-#ifndef TCIOFLUSH
-#define TCIOFLUSH 2
-#endif
- int flshcmd = TCIOFLUSH;
-
- (void) ioctl(parse->generic->io.fd, TCFLSH, (caddr_t)&flshcmd);
- }
-#endif
-#endif
-
- /*
- * try to do any special initializations
- */
- if (parse->parse_type->cl_init)
- {
- if (parse->parse_type->cl_init(parse))
- {
- parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
- return 0; /* well, ok - special initialisation broke */
- }
- }
-
- /*
- * 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-1999, Frank Kardel");
- notice = 1;
- }
-
- /*
- * print out configuration
- */
- NLOG(NLOG_CLOCKINFO)
- {
- /* conditional if clause for conditional syslog */
- msyslog(LOG_INFO, "PARSE receiver #%d: reference clock \"%s\" (device %s) added",
- CLK_UNIT(parse->peer),
- parse->parse_type->cl_description, parsedev);
-
- msyslog(LOG_INFO, "PARSE receiver #%d: Stratum %d, %sPPS support, 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);
-
- msyslog(LOG_INFO, "PARSE receiver #%d: rootdelay %.6f s, phaseadjust %.6f s, %s IO handling",
- CLK_UNIT(parse->peer),
- parse->parse_type->cl_rootdelay,
- parse->generic->fudgetime1,
- parse->binding->bd_description);
-
- 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 ");
-#endif
- }
-
- return 1;
-}
-
-/*--------------------------------------------------
- * parse_poll - called by the transmit procedure
- */
-static void
-parse_poll(
- int unit,
- struct peer *peer
- )
-{
- struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr;
-
- if (peer != parse->peer)
- {
- msyslog(LOG_ERR,
- "PARSE receiver #%d: poll: INTERNAL: peer incorrect",
- unit);
- return;
- }
-
- /*
- * Update clock stat counters
- */
- parse->generic->polls++;
-
- if (parse->pollneeddata &&
- ((current_time - parse->pollneeddata) > (1<<(max(min(parse->peer->hpoll, parse->peer->ppoll), parse->peer->minpoll)))))
- {
- /*
- * 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));
- }
-
- /*
- * we just mark that we want the next sample for the clock filter
- */
- parse->pollneeddata = current_time;
-
- if (parse->parse_type->cl_poll)
- {
- parse->parse_type->cl_poll(parse);
- }
-
- cparse_statistics(parse);
-
- return;
-}
-
-#define LEN_STATES 300 /* length of state string */
-
-/*--------------------------------------------------
- * parse_control - set fudge factors, return statistics
- */
-static void
-parse_control(
- int unit,
- struct refclockstat *in,
- struct refclockstat *out,
- struct peer *peer
- )
-{
- register struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr;
- parsectl_t tmpctl;
-
- static char outstatus[400]; /* status output buffer */
-
- if (out)
- {
- out->lencode = 0;
- out->p_lastcode = 0;
- out->kv_list = (struct ctl_var *)0;
- }
-
- if (!parse || !parse->peer)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_control: unit invalid (UNIT INACTIVE)",
- unit);
- return;
- }
-
- 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);
- }
- }
-
- if (out)
- {
- u_long sum = 0;
- char *t, *tt, *start;
- int i;
-
- outstatus[0] = '\0';
-
- out->type = REFCLK_PARSE;
- out->haveflags |= CLK_HAVETIME2;
-
- /*
- * figure out skew between PPS and RS232 - just for informational
- * purposes - returned in time2 value
- */
- if (PARSE_SYNC(parse->time.parse_state))
- {
- if (PARSE_PPS(parse->time.parse_state) && PARSE_TIMECODE(parse->time.parse_state))
- {
- l_fp off;
-
- /*
- * 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 */
- tt = add_var(&out->kv_list, 80, RO);
- sprintf(tt, "refclock_ppsskew=%s", lfptoms(&off, 6));
- }
- }
-
- if (PARSE_PPS(parse->time.parse_state))
- {
- tt = add_var(&out->kv_list, 80, RO|DEF);
- sprintf(tt, "refclock_ppstime=\"%s\"", gmprettydate(&parse->time.parse_ptime.fp));
- }
-
- tt = add_var(&out->kv_list, 128, RO|DEF);
- sprintf(tt, "refclock_time=\"");
- tt += strlen(tt);
-
- if (parse->time.parse_time.fp.l_ui == 0)
- {
- strcpy(tt, "<UNDEFINED>\"");
- }
- else
- {
- sprintf(tt, "%s\"", gmprettydate(&parse->time.parse_time.fp));
- t = tt + strlen(tt);
- }
-
- if (!PARSE_GETTIMECODE(parse, &tmpctl))
- {
- ERR(ERR_INTERNAL)
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_control: parse_timecode() FAILED", unit);
- }
- else
- {
- tt = add_var(&out->kv_list, 512, RO|DEF);
- sprintf(tt, "refclock_status=\"");
- tt += strlen(tt);
-
- /*
- * copy PPS flags from last read transaction (informational only)
- */
- tmpctl.parsegettc.parse_state |= parse->time.parse_state &
- (PARSEB_PPS|PARSEB_S_PPS);
-
- (void) parsestate(tmpctl.parsegettc.parse_state, tt);
-
- strcat(tt, "\"");
-
- 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));
-
- parse->generic->badformat += tmpctl.parsegettc.parse_badformat;
- }
-
- tmpctl.parseformat.parse_format = tmpctl.parsegettc.parse_format;
-
- if (!PARSE_GETFMT(parse, &tmpctl))
- {
- ERR(ERR_INTERNAL)
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_control: parse_getfmt() FAILED", unit);
- }
- else
- {
- tt = add_var(&out->kv_list, 80, RO|DEF);
- sprintf(tt, "refclock_format=\"");
-
- strncat(tt, tmpctl.parseformat.parse_buffer, tmpctl.parseformat.parse_count);
- strcat(tt,"\"");
- }
-
- /*
- * gather state statistics
- */
-
- start = tt = add_var(&out->kv_list, LEN_STATES, RO|DEF);
- strcpy(tt, "refclock_states=\"");
- tt += strlen(tt);
-
- for (i = 0; i <= CEVNT_MAX; i++)
- {
- u_long s_time;
- u_long d = current_time - parse->generic->timestarted;
- u_long percent;
-
- percent = s_time = PARSE_STATETIME(parse, i);
-
- while (((u_long)(~0) / 10000) < percent)
- {
- percent /= 10;
- d /= 10;
- }
-
- if (d)
- percent = (percent * 10000) / d;
- else
- percent = 10000;
-
- if (s_time)
- {
- char item[80];
- int count;
-
- sprintf(item, "%s%s%s: %s (%d.%02d%%)",
- sum ? "; " : "",
- (parse->generic->currentstatus == i) ? "*" : "",
- clockstatus((unsigned int)i),
- l_mktime(s_time),
- (int)(percent / 100), (int)(percent % 100));
- if ((count = strlen(item)) < (LEN_STATES - 40 - (tt - start)))
- {
- strcpy(tt, item);
- tt += count;
- }
- sum += s_time;
- }
- }
-
- sprintf(tt, "; running time: %s\"", l_mktime(sum));
-
- tt = add_var(&out->kv_list, 32, RO);
- sprintf(tt, "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);
-
- tt = add_var(&out->kv_list, 128, RO);
- sprintf(tt, "refclock_driver_version=\"%s\"", rcsid);
-
- {
- struct ctl_var *k;
-
- k = parse->kv;
- while (k && !(k->flags & EOV))
- {
- set_var(&out->kv_list, k->text, strlen(k->text)+1, k->flags);
- k++;
- }
- }
-
- out->lencode = strlen(outstatus);
- out->p_lastcode = outstatus;
- }
-}
-
-/**===========================================================================
- ** processing routines
- **/
-
-/*--------------------------------------------------
- * event handling - note that nominal events will also be posted
- */
-static void
-parse_event(
- struct parseunit *parse,
- int event
- )
-{
- if (parse->generic->currentstatus != (u_char) 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
- {
- 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);
- }
-}
-
-/*--------------------------------------------------
- * process a PARSE time sample
- */
-static void
-parse_process(
- struct parseunit *parse,
- parsetime_t *parsetime
- )
-{
- l_fp off, rectime, reftime;
- double fudge;
-
- /*
- * check for changes in conversion status
- * (only one for each new status !)
- */
- if (((parsetime->parse_status & CVT_MASK) != CVT_OK) &&
- ((parsetime->parse_status & CVT_MASK) != CVT_NONE) &&
- (parse->time.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));
-
- if ((parsetime->parse_status & CVT_MASK) == CVT_FAIL)
- {
- /*
- * tell more about the story - list time code
- * there is a slight change for a race condition and
- * the time code might be overwritten by the next packet
- */
- parsectl_t tmpctl;
-
- if (!PARSE_GETTIMECODE(parse, &tmpctl))
- {
- ERR(ERR_INTERNAL)
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_process: parse_timecode() FAILED", CLK_UNIT(parse->peer));
- }
- else
- {
- ERR(ERR_BADDATA)
- msyslog(LOG_WARNING, "PARSE receiver #%d: FAILED TIMECODE: \"%s\" (check receiver configuration / cableling)",
- 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;
- }
- }
- }
-
- /*
- * examine status and post appropriate events
- */
- if ((parsetime->parse_status & CVT_MASK) != CVT_OK)
- {
- /*
- * got bad data - tell the rest of the system
- */
- switch (parsetime->parse_status & CVT_MASK)
- {
- case CVT_NONE:
- if ((parsetime->parse_status & CVT_ADDITIONAL) &&
- parse->parse_type->cl_message)
- parse->parse_type->cl_message(parse, parsetime);
- 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);
- }
- else
- if (parsetime->parse_status & CVT_BADDATE)
- {
- parse_event(parse, CEVNT_BADDATE);
- }
- else
- if (parsetime->parse_status & CVT_BADTIME)
- {
- parse_event(parse, CEVNT_BADTIME);
- }
- else
- {
- parse_event(parse, CEVNT_BADREPLY); /* for the lack of something better */
- }
- }
- return; /* skip the rest - useless */
- }
-
- /*
- * check for format changes
- * (in case somebody has swapped clocks 8-)
- */
- if (parse->lastformat != parsetime->parse_format)
- {
- parsectl_t tmpctl;
-
- tmpctl.parseformat.parse_format = parsetime->parse_format;
-
- if (!PARSE_GETFMT(parse, &tmpctl))
- {
- ERR(ERR_INTERNAL)
- msyslog(LOG_ERR, "PARSE receiver #%d: parse_getfmt() FAILED", CLK_UNIT(parse->peer));
- }
- else
- {
- NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
- msyslog(LOG_INFO, "PARSE receiver #%d: packet format \"%s\"",
- CLK_UNIT(parse->peer), tmpctl.parseformat.parse_buffer);
- }
- parse->lastformat = parsetime->parse_format;
- }
-
- /*
- * now, any changes ?
- */
- if (parse->time.parse_state != parsetime->parse_state)
- {
- char tmp1[200];
- char tmp2[200];
- /*
- * something happend
- */
-
- (void) parsestate(parsetime->parse_state, tmp1);
- (void) parsestate(parse->time.parse_state, tmp2);
-
- NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
- msyslog(LOG_INFO,"PARSE receiver #%d: STATE CHANGE: %s -> %s",
- CLK_UNIT(parse->peer), tmp2, tmp1);
- }
-
- /*
- * remember for future
- */
- parse->time = *parsetime;
-
- /*
- * check to see, whether the clock did a complete powerup or lost PZF signal
- * and post correct events for current condition
- */
- if (PARSE_POWERUP(parsetime->parse_state))
- {
- /*
- * this is bad, as we have completely lost synchronisation
- * well this is a problem with the receiver here
- * for PARSE Meinberg DCF77 receivers the lost synchronisation
- * is true as it is the powerup state and the time is taken
- * from a crude real time clock chip
- * for the PZF series this is only partly true, as
- * PARSE_POWERUP only means that the pseudo random
- * phase shift sequence cannot be found. this is only
- * bad, if we have never seen the clock in the SYNC
- * state, where the PHASE and EPOCH are correct.
- * for reporting events the above business does not
- * really matter, but we can use the time code
- * even in the POWERUP state after having seen
- * the clock in the synchronized state (PZF class
- * receivers) unless we have had a telegram disruption
- * after having seen the clock in the SYNC state. we
- * thus require having seen the clock in SYNC state
- * *after* having missed telegrams (noresponse) from
- * the clock. one problem remains: we might use erroneously
- * POWERUP data if the disruption is shorter than 1 polling
- * interval. fortunately powerdowns last usually longer than 64
- * seconds and the receiver is at least 2 minutes in the
- * POWERUP or NOSYNC state before switching to SYNC
- */
- parse_event(parse, CEVNT_FAULT);
- NLOG(NLOG_CLOCKSTATUS)
- ERR(ERR_BADSTATUS)
- msyslog(LOG_ERR,"PARSE receiver #%d: NOT SYNCHRONIZED",
- CLK_UNIT(parse->peer));
- }
- else
- {
- /*
- * we have two states left
- *
- * SYNC:
- * this state means that the EPOCH (timecode) and PHASE
- * information has be read correctly (at least two
- * successive PARSE timecodes were received correctly)
- * this is the best possible state - full trust
- *
- * NOSYNC:
- * The clock should be on phase with respect to the second
- * signal, but the timecode has not been received correctly within
- * at least the last two minutes. this is a sort of half baked state
- * for PARSE Meinberg DCF77 clocks this is bad news (clock running
- * without timecode confirmation)
- * PZF 535 has also no time confirmation, but the phase should be
- * very precise as the PZF signal can be decoded
- */
-
- if (PARSE_SYNC(parsetime->parse_state))
- {
- /*
- * currently completely synchronized - best possible state
- */
- parse->lastsync = current_time;
- clear_err(parse, ERR_BADSTATUS);
- }
- else
- {
- /*
- * we have had some problems receiving the time code
- */
- parse_event(parse, CEVNT_PROP);
- NLOG(NLOG_CLOCKSTATUS)
- ERR(ERR_BADSTATUS)
- msyslog(LOG_ERR,"PARSE receiver #%d: TIMECODE NOT CONFIRMED",
- CLK_UNIT(parse->peer));
- }
- }
-
- fudge = parse->generic->fudgetime1; /* standard RS232 Fudgefactor */
-
- if (PARSE_TIMECODE(parsetime->parse_state))
- {
- rectime = parsetime->parse_stime.fp;
- off = reftime = parsetime->parse_time.fp;
-
- L_SUB(&off, &rectime); /* prepare for PPS adjustments logic */
-
-#ifdef DEBUG
- if (debug > 3)
- printf("PARSE receiver #%d: Reftime %s, Recvtime %s - initial offset %s\n",
- CLK_UNIT(parse->peer),
- prettydate(&reftime),
- prettydate(&rectime),
- lfptoa(&off,6));
-#endif
- }
-
- if (PARSE_PPS(parsetime->parse_state) && CLK_PPS(parse->peer))
- {
- l_fp offset;
-
- /*
- * we have a PPS signal - much better than the RS232 stuff (we hope)
- */
- offset = parsetime->parse_ptime.fp;
-
-#ifdef DEBUG
- if (debug > 3)
- printf("PARSE receiver #%d: PPStime %s\n",
- CLK_UNIT(parse->peer),
- prettydate(&offset));
-#endif
- if (PARSE_TIMECODE(parsetime->parse_state))
- {
- 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 */
-
- /*
- * RS232 offsets within [-0.5..0.5[ - take PPS offsets
- */
-
- if (parse->parse_type->cl_flags & PARSE_F_PPSONSECOND)
- {
- reftime = off = offset;
- if (reftime.l_uf & (unsigned)0x80000000)
- reftime.l_ui++;
- reftime.l_uf = 0;
-
-
- /*
- * implied on second offset
- */
- off.l_uf = ~off.l_uf; /* map [0.5..1[ -> [-0.5..0[ */
- off.l_ui = (off.l_f < 0) ? ~0 : 0; /* sign extend */
- }
- else
- {
- /*
- * time code describes pulse
- */
- reftime = off = parsetime->parse_time.fp;
-
- L_SUB(&off, &offset); /* true offset */
- }
- }
- /*
- * take RS232 offset when PPS when out of bounds
- */
- }
- else
- {
- fudge = parse->generic->fudgetime2; /* 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[
- */
- off = offset;
- reftime = offset;
- if (reftime.l_uf & (unsigned)0x80000000)
- reftime.l_ui++;
- reftime.l_uf = 0;
- /*
- * implied on second offset
- */
- off.l_uf = ~off.l_uf; /* map [0.5..1[ -> [-0.5..0[ */
- off.l_ui = (off.l_f < 0) ? ~0 : 0; /* sign extend */
- }
- }
- else
- {
- if (!PARSE_TIMECODE(parsetime->parse_state))
- {
- /*
- * Well, no PPS, no TIMECODE, no more work ...
- */
- if ((parsetime->parse_status & CVT_ADDITIONAL) &&
- parse->parse_type->cl_message)
- parse->parse_type->cl_message(parse, parsetime);
- return;
- }
- }
-
-#ifdef DEBUG
- if (debug > 3)
- printf("PARSE receiver #%d: Reftime %s, Recvtime %s - final offset %s\n",
- CLK_UNIT(parse->peer),
- prettydate(&reftime),
- prettydate(&rectime),
- lfptoa(&off,6));
-#endif
-
-
- rectime = reftime;
- L_SUB(&rectime, &off); /* just to keep the ntp interface happy */
-
-#ifdef DEBUG
- if (debug > 3)
- printf("PARSE receiver #%d: calculated Reftime %s, Recvtime %s\n",
- CLK_UNIT(parse->peer),
- prettydate(&reftime),
- prettydate(&rectime));
-#endif
-
- if ((parsetime->parse_status & CVT_ADDITIONAL) &&
- parse->parse_type->cl_message)
- parse->parse_type->cl_message(parse, parsetime);
-
- if (PARSE_SYNC(parsetime->parse_state))
- {
- /*
- * log OK status
- */
- parse_event(parse, CEVNT_NOMINAL);
- }
-
- clear_err(parse, ERR_BADIO);
- clear_err(parse, ERR_BADDATA);
- 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
- * see the clock states section above for more reasoning
- */
- if (((current_time - parse->lastsync) > parse->parse_type->cl_maxunsync) ||
- (parse->lastsync <= parse->lastmissed))
- {
- parse->generic->leap = LEAP_NOTINSYNC;
- }
- else
- {
- if (PARSE_LEAPADD(parsetime->parse_state))
- {
- /*
- * we pick this state also for time code that pass leap warnings
- * without direction information (as earth is currently slowing
- * down).
- */
- parse->generic->leap = (parse->flags & PARSE_LEAP_DELETE) ? LEAP_DELSECOND : LEAP_ADDSECOND;
- }
- else
- if (PARSE_LEAPDEL(parsetime->parse_state))
- {
- parse->generic->leap = LEAP_DELSECOND;
- }
- else
- {
- parse->generic->leap = LEAP_NOWARNING;
- }
- }
-
- /*
- * ready, unless the machine wants a sample
- */
- if (!parse->pollneeddata)
- return;
-
- parse->pollneeddata = 0;
-
- refclock_receive(parse->peer);
-}
-
-/**===========================================================================
- ** special code for special clocks
- **/
-
-static void
-mk_utcinfo(
- char *t,
- int wnt,
- int wnlsf,
- int dn,
- int dtls,
- int dtlsf
- )
-{
- l_fp leapdate;
-
- sprintf(t, "current correction %d sec", dtls);
- t += strlen(t);
-
- if (wnlsf < 990)
- wnlsf += 1024;
-
- if (wnt < 990)
- wnt += 1024;
-
- gpstolfp((unsigned short)wnlsf, (unsigned short)dn, 0, &leapdate);
-
- if ((dtlsf != dtls) &&
- ((wnlsf - wnt) < 52))
- {
- sprintf(t, ", next correction %d sec on %s, new GPS-UTC offset %d",
- dtlsf - dtls, gmprettydate(&leapdate), dtlsf);
- }
- else
- {
- sprintf(t, ", last correction on %s",
- gmprettydate(&leapdate));
- }
-}
-
-#ifdef CLOCK_MEINBERG
-/**===========================================================================
- ** Meinberg GPS166/GPS167 support
- **/
-
-/*------------------------------------------------------------
- * gps16x_message - process GPS16x messages
- */
-static void
-gps16x_message(
- struct parseunit *parse,
- parsetime_t *parsetime
- )
-{
- if (parse->time.parse_msglen && parsetime->parse_msg[0] == SOH)
- {
- GPS_MSG_HDR header;
- unsigned char *bufp = (unsigned char *)parsetime->parse_msg + 1;
-
-#ifdef DEBUG
- if (debug > 2)
- {
- char msgbuffer[600];
-
- mkreadable(msgbuffer, sizeof(msgbuffer), (char *)parsetime->parse_msg, parsetime->parse_msglen, 1);
- printf("PARSE receiver #%d: received message (%d bytes) >%s<\n",
- CLK_UNIT(parse->peer),
- parsetime->parse_msglen,
- msgbuffer);
- }
-#endif
- get_mbg_header(&bufp, &header);
- if (header.gps_hdr_csum == mbg_csum(parsetime->parse_msg + 1, 6) &&
- (header.gps_len == 0 ||
- (header.gps_len < sizeof(parsetime->parse_msg) &&
- header.gps_data_csum == mbg_csum(bufp, header.gps_len))))
- {
- /*
- * clean message
- */
- switch (header.gps_cmd)
- {
- case GPS_SW_REV:
- {
- char buffer[64];
- SW_REV gps_sw_rev;
-
- get_mbg_sw_rev(&bufp, &gps_sw_rev);
- sprintf(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);
- }
- break;
-
- case GPS_STAT:
- {
- static struct state
- {
- unsigned short flag; /* status flag */
- unsigned const char *string; /* bit name */
- } states[] =
- {
- { TM_ANT_DISCONN, (const unsigned char *)"ANTENNA FAULTY" },
- { TM_SYN_FLAG, (const unsigned char *)"NO SYNC SIGNAL" },
- { TM_NO_SYNC, (const unsigned char *)"NO SYNC POWERUP" },
- { TM_NO_POS, (const unsigned char *)"NO POSITION" },
- { 0, (const unsigned char *)"" }
- };
- unsigned short status;
- struct state *s = states;
- char buffer[512];
- char *p, *b;
-
- status = get_lsb_short(&bufp);
- sprintf(buffer, "meinberg_gps_status=\"[0x%04x] ", status);
-
- if (status)
- {
- p = b = buffer + strlen(buffer);
- while (s->flag)
- {
- if (status & s->flag)
- {
- if (p != b)
- {
- *p++ = ',';
- *p++ = ' ';
- }
-
- strcat(p, (const char *)s->string);
- }
- s++;
- }
-
- *p++ = '"';
- *p = '\0';
- }
- else
- {
- strcat(buffer, "<OK>\"");
- }
-
- set_var(&parse->kv, buffer, 64, RO|DEF);
- }
- break;
-
- case GPS_POS_XYZ:
- {
- XYZ xyz;
- char buffer[256];
-
- get_mbg_xyz(&bufp, xyz);
- sprintf(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));
-
- set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF);
- }
- break;
-
- case GPS_POS_LLA:
- {
- LLA lla;
- char buffer[256];
-
- get_mbg_lla(&bufp, lla);
-
- sprintf(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));
-
- set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF);
- }
- break;
-
- case GPS_TZDL:
- break;
-
- case GPS_PORT_PARM:
- break;
-
- case GPS_SYNTH:
- break;
-
- case GPS_ANT_INFO:
- {
- ANT_INFO antinfo;
- u_char buffer[512];
- u_char *p;
-
- get_mbg_antinfo(&bufp, &antinfo);
- sprintf(buffer, "meinberg_antenna_status=\"");
- p = buffer + strlen(buffer);
-
- switch (antinfo.status)
- {
- case ANT_INVALID:
- strcat(p, "<OK>");
- p += strlen(p);
- break;
-
- case ANT_DISCONN:
- strcat(p, "DISCONNECTED since ");
- 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);
- *p = '\0';
- break;
-
- case ANT_RECONN:
- strcat(p, "RECONNECTED on ");
- p += strlen(p);
- mbg_tm_str(&p, &antinfo.tm_reconn);
- sprintf(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);
- *p = '\0';
- break;
-
- default:
- sprintf(p, "bad status 0x%04x", antinfo.status);
- p += strlen(p);
- break;
- }
-
- *p++ = '"';
- *p = '\0';
-
- set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF);
- }
- break;
-
- case GPS_UCAP:
- break;
-
- case GPS_CFGH:
- {
- CFGH cfgh;
- u_char buffer[512];
- u_char *p;
-
- get_mbg_cfgh(&bufp, &cfgh);
- if (cfgh.valid)
- {
- int i;
-
- p = buffer;
- strcpy(buffer, "gps_tot_51=\"");
- p += strlen(p);
- mbg_tgps_str(&p, &cfgh.tot_51);
- *p++ = '"';
- *p = '\0';
- set_var(&parse->kv, buffer, sizeof(buffer), RO);
-
- p = buffer;
- strcpy(buffer, "gps_tot_63=\"");
- p += strlen(p);
- mbg_tgps_str(&p, &cfgh.tot_63);
- *p++ = '"';
- *p = '\0';
- set_var(&parse->kv, buffer, sizeof(buffer), RO);
-
- p = buffer;
- strcpy(buffer, "gps_t0a=\"");
- p += strlen(p);
- mbg_tgps_str(&p, &cfgh.t0a);
- *p++ = '"';
- *p = '\0';
- set_var(&parse->kv, buffer, sizeof(buffer), RO);
-
- for (i = MIN_SVNO; i <= MAX_SVNO; i++)
- {
- p = buffer;
- sprintf(p, "gps_cfg[%d]=\"[0x%x] ", i, cfgh.cfg[i]);
- p += strlen(p);
- switch (cfgh.cfg[i] & 0x7)
- {
- case 0:
- strcpy(p, "BLOCK I");
- break;
- case 1:
- strcpy(p, "BLOCK II");
- break;
- default:
- sprintf(p, "bad CFG");
- break;
- }
- strcat(p, "\"");
- set_var(&parse->kv, buffer, sizeof(buffer), RO);
-
- p = buffer;
- sprintf(p, "gps_health[%d]=\"[0x%x] ", i, cfgh.health[i]);
- p += strlen(p);
- switch ((cfgh.health[i] >> 5) & 0x7 )
- {
- case 0:
- strcpy(p, "OK;");
- break;
- case 1:
- strcpy(p, "PARITY;");
- break;
- case 2:
- strcpy(p, "TLM/HOW;");
- break;
- case 3:
- strcpy(p, "Z-COUNT;");
- break;
- case 4:
- strcpy(p, "SUBFRAME 1,2,3;");
- break;
- case 5:
- strcpy(p, "SUBFRAME 4,5;");
- break;
- case 6:
- strcpy(p, "UPLOAD BAD;");
- break;
- case 7:
- strcpy(p, "DATA BAD;");
- break;
- }
-
- p += strlen(p);
-
- switch (cfgh.health[i] & 0x1F)
- {
- case 0:
- strcpy(p, "SIGNAL OK");
- break;
- case 0x1C:
- strcpy(p, "SV TEMP OUT");
- break;
- case 0x1D:
- strcpy(p, "SV WILL BE TEMP OUT");
- break;
- case 0x1E:
- break;
- case 0x1F:
- strcpy(p, "MULTIPLE ERRS");
- break;
- default:
- strcpy(p, "TRANSMISSION PROBLEMS");
- break;
- }
-
- strcat(p, "\"");
- set_var(&parse->kv, buffer, sizeof(buffer), RO);
- }
- }
- }
- break;
-
- case GPS_ALM:
- break;
-
- case GPS_EPH:
- break;
-
- case GPS_UTC:
- {
- UTC utc;
- char buffer[512];
- char *p;
-
- p = buffer;
-
- get_mbg_utc(&bufp, &utc);
-
- if (utc.valid)
- {
- strcpy(p, "gps_utc_correction=\"");
- p += strlen(p);
- mk_utcinfo(p, utc.t0t.wn, utc.WNlsf, utc.DNt, utc.delta_tls, utc.delta_tlsf);
- strcat(p, "\"");
- }
- else
- {
- strcpy(p, "gps_utc_correction=\"<NO UTC DATA>\"");
- }
- set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF);
- }
- break;
-
- case GPS_IONO:
- break;
-
- case GPS_ASCII_MSG:
- {
- ASCII_MSG gps_ascii_msg;
- char buffer[128];
-
- get_mbg_ascii_msg(&bufp, &gps_ascii_msg);
-
- if (gps_ascii_msg.valid)
- {
- char buffer1[128];
- mkreadable(buffer1, sizeof(buffer1), gps_ascii_msg.s, strlen(gps_ascii_msg.s), (int)0);
-
- sprintf(buffer, "gps_message=\"%s\"", buffer1);
- }
- else
- strcpy(buffer, "gps_message=<NONE>");
-
- set_var(&parse->kv, buffer, 128, RO|DEF);
- }
-
- break;
-
- default:
- break;
- }
- }
- else
- {
- msyslog(LOG_DEBUG, "PARSE receiver #%d: gps16x_message: message checksum error: hdr_csum = 0x%x (expected 0x%lx), data_len = %d, data_csum = 0x%x (expected 0x%lx)",
- CLK_UNIT(parse->peer),
- header.gps_hdr_csum, mbg_csum(parsetime->parse_msg + 1, 6),
- header.gps_len,
- header.gps_data_csum, mbg_csum(bufp, (unsigned)((header.gps_len < sizeof(parsetime->parse_msg)) ? header.gps_len : 0)));
- }
- }
-
- return;
-}
-
-/*------------------------------------------------------------
- * gps16x_poll - query the reciver peridically
- */
-static void
-gps16x_poll(
- struct peer *peer
- )
-{
- struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr;
-
- static GPS_MSG_HDR sequence[] =
- {
- { GPS_SW_REV, 0, 0, 0 },
- { GPS_STAT, 0, 0, 0 },
- { GPS_UTC, 0, 0, 0 },
- { GPS_ASCII_MSG, 0, 0, 0 },
- { GPS_ANT_INFO, 0, 0, 0 },
- { GPS_CFGH, 0, 0, 0 },
- { GPS_POS_XYZ, 0, 0, 0 },
- { GPS_POS_LLA, 0, 0, 0 },
- { (unsigned short)~0, 0, 0, 0 }
- };
-
- int rtc;
- unsigned char cmd_buffer[64];
- unsigned char *outp = cmd_buffer;
- GPS_MSG_HDR *header;
-
- if (((poll_info_t *)parse->parse_type->cl_data)->rate)
- {
- parse->peer->nextaction = current_time + ((poll_info_t *)parse->parse_type->cl_data)->rate;
- }
-
- if (sequence[parse->localstate].gps_cmd == (unsigned short)~0)
- parse->localstate = 0;
-
- header = sequence + parse->localstate++;
-
- *outp++ = SOH; /* start command */
-
- put_mbg_header(&outp, header);
- outp = cmd_buffer + 1;
-
- header->gps_hdr_csum = (short)mbg_csum(outp, 6);
- put_mbg_header(&outp, header);
-
-#ifdef DEBUG
- if (debug > 2)
- {
- char buffer[128];
-
- mkreadable(buffer, sizeof(buffer), (char *)cmd_buffer, (unsigned)(outp - cmd_buffer), 1);
- printf("PARSE receiver #%d: transmitted message #%ld (%d bytes) >%s<\n",
- CLK_UNIT(parse->peer),
- parse->localstate - 1,
- (int)(outp - cmd_buffer),
- buffer);
- }
-#endif
-
- rtc = write(parse->generic->io.fd, cmd_buffer, (unsigned long)(outp - cmd_buffer));
-
- if (rtc < 0)
- {
- ERR(ERR_BADIO)
- msyslog(LOG_ERR, "PARSE receiver #%d: gps16x_poll: failed to send cmd to clock: %m", CLK_UNIT(parse->peer));
- }
- else
- if (rtc != outp - cmd_buffer)
- {
- ERR(ERR_BADIO)
- msyslog(LOG_ERR, "PARSE receiver #%d: gps16x_poll: failed to send cmd incomplete (%d of %d bytes sent)", CLK_UNIT(parse->peer), rtc, (int)(outp - cmd_buffer));
- }
-
- clear_err(parse, ERR_BADIO);
- return;
-}
-
-/*--------------------------------------------------
- * init routine - setup timer
- */
-static int
-gps16x_poll_init(
- struct parseunit *parse
- )
-{
- if (((poll_info_t *)parse->parse_type->cl_data)->rate)
- {
- parse->peer->action = gps16x_poll;
- gps16x_poll(parse->peer);
- }
-
- return 0;
-}
-
-#else
-static void
-gps16x_message(
- struct parseunit *parse,
- parsetime_t *parsetime
- )
-{}
-static int
-gps16x_poll_init(
- struct parseunit *parse
- )
-{
- return 1;
-}
-#endif /* CLOCK_MEINBERG */
-
-/**===========================================================================
- ** clock polling support
- **/
-
-/*--------------------------------------------------
- * direct poll routine
- */
-static void
-poll_dpoll(
- struct parseunit *parse
- )
-{
- int rtc;
- const char *ps = ((poll_info_t *)parse->parse_type->cl_data)->string;
- int ct = ((poll_info_t *)parse->parse_type->cl_data)->count;
-
- rtc = write(parse->generic->io.fd, ps, (unsigned long)ct);
- if (rtc < 0)
- {
- ERR(ERR_BADIO)
- msyslog(LOG_ERR, "PARSE receiver #%d: poll_dpoll: failed to send cmd to clock: %m", CLK_UNIT(parse->peer));
- }
- else
- if (rtc != ct)
- {
- ERR(ERR_BADIO)
- msyslog(LOG_ERR, "PARSE receiver #%d: poll_dpoll: failed to send cmd incomplete (%d of %d bytes sent)", CLK_UNIT(parse->peer), rtc, ct);
- }
- clear_err(parse, ERR_BADIO);
-}
-
-/*--------------------------------------------------
- * periodic poll routine
- */
-static void
-poll_poll(
- struct peer *peer
- )
-{
- struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr;
-
- if (parse->parse_type->cl_poll)
- parse->parse_type->cl_poll(parse);
-
- if (((poll_info_t *)parse->parse_type->cl_data)->rate)
- {
- parse->peer->nextaction = current_time + ((poll_info_t *)parse->parse_type->cl_data)->rate;
- }
-}
-
-/*--------------------------------------------------
- * init routine - setup timer
- */
-static int
-poll_init(
- struct parseunit *parse
- )
-{
- if (((poll_info_t *)parse->parse_type->cl_data)->rate)
- {
- parse->peer->action = poll_poll;
- poll_poll(parse->peer);
- }
-
- return 0;
-}
-
-/**===========================================================================
- ** Trimble support
- **/
-
-/*-------------------------------------------------------------
- * trimble TAIP init routine - setup EOL and then do poll_init.
- */
-static int
-trimbletaip_init(
- struct parseunit *parse
- )
-{
-#ifdef HAVE_TERMIOS
- struct termios tio;
-#endif
-#ifdef HAVE_SYSV_TTYS
- struct termio tio;
-#endif
- /*
- * configure terminal line for trimble receiver
- */
- if (TTY_GETATTR(parse->generic->io.fd, &tio) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_init: tcgetattr(fd, &tio): %m", CLK_UNIT(parse->peer));
- return 0;
- }
- else
- {
- tio.c_cc[VEOL] = TRIMBLETAIP_EOL;
-
- if (TTY_SETATTR(parse->generic->io.fd, &tio) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_init: tcsetattr(fd, &tio): %m", CLK_UNIT(parse->peer));
- return 0;
- }
- }
- return poll_init(parse);
-}
-
-/*--------------------------------------------------
- * trimble TAIP event routine - reset receiver upon data format trouble
- */
-static const char *taipinit[] = {
- ">FPV00000000<",
- ">SRM;ID_FLAG=F;CS_FLAG=T;EC_FLAG=F;FR_FLAG=T;CR_FLAG=F<",
- ">FTM00020001<",
- (char *)0
-};
-
-static void
-trimbletaip_event(
- struct parseunit *parse,
- int event
- )
-{
- switch (event)
- {
- case CEVNT_BADREPLY: /* reset on garbled input */
- case CEVNT_TIMEOUT: /* reset on no input */
- {
- const char **iv;
-
- iv = taipinit;
- while (*iv)
- {
- int rtc = write(parse->generic->io.fd, *iv, strlen(*iv));
- if (rtc < 0)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_event: failed to send cmd to clock: %m", CLK_UNIT(parse->peer));
- return;
- }
- else
- {
- if (rtc != strlen(*iv))
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_event: failed to send cmd incomplete (%d of %d bytes sent)",
- CLK_UNIT(parse->peer), rtc, (int)strlen(*iv));
- return;
- }
- }
- iv++;
- }
-
- NLOG(NLOG_CLOCKINFO)
- ERR(ERR_BADIO)
- msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_event: RECEIVER INITIALIZED",
- CLK_UNIT(parse->peer));
- }
- break;
-
- default: /* ignore */
- break;
- }
-}
-
-/*
- * This driver supports the Trimble SVee Six Plus GPS receiver module.
- * It should support other Trimble receivers which use the Trimble Standard
- * Interface Protocol (see below).
- *
- * The module has a serial I/O port for command/data and a 1 pulse-per-second
- * output, about 1 microsecond wide. The leading edge of the pulse is
- * coincident with the change of the GPS second. This is the same as
- * the change of the UTC second +/- ~1 microsecond. Some other clocks
- * specifically use a feature in the data message as a timing reference, but
- * the SVee Six Plus does not do this. In fact there is considerable jitter
- * on the timing of the messages, so this driver only supports the use
- * of the PPS pulse for accurate timing. Where it is determined that
- * the offset is way off, when first starting up ntpd for example,
- * the timing of the data stream is used until the offset becomes low enough
- * (|offset| < CLOCK_MAX), at which point the pps offset is used.
- *
- * It can use either option for receiving PPS information - the 'ppsclock'
- * stream pushed onto the serial data interface to timestamp the Carrier
- * Detect interrupts, where the 1PPS connects to the CD line. This only
- * works on SunOS 4.1.x currently. To select this, define PPSPPS in
- * Config.local. The other option is to use a pulse-stretcher/level-converter
- * to convert the PPS pulse into a RS232 start pulse & feed this into another
- * tty port. To use this option, define PPSCLK in Config.local. The pps input,
- * by whichever method, is handled in ntp_loopfilter.c
- *
- * The receiver uses a serial message protocol called Trimble Standard
- * Interface Protocol (it can support others but this driver only supports
- * TSIP). Messages in this protocol have the following form:
- *
- * <DLE><id> ... <data> ... <DLE><ETX>
- *
- * Any bytes within the <data> portion of value 10 hex (<DLE>) are doubled
- * on transmission and compressed back to one on reception. Otherwise
- * the values of data bytes can be anything. The serial interface is RS-422
- * asynchronous using 9600 baud, 8 data bits with odd party (**note** 9 bits
- * in total!), and 1 stop bit. The protocol supports byte, integer, single,
- * and double datatypes. Integers are two bytes, sent most significant first.
- * Singles are IEEE754 single precision floating point numbers (4 byte) sent
- * sign & exponent first. Doubles are IEEE754 double precision floating point
- * numbers (8 byte) sent sign & exponent first.
- * The receiver supports a large set of messages, only a small subset of
- * which are used here. From driver to receiver the following are used:
- *
- * ID Description
- *
- * 21 Request current time
- * 22 Mode Select
- * 2C Set/Request operating parameters
- * 2F Request UTC info
- * 35 Set/Request I/O options
-
- * From receiver to driver the following are recognised:
- *
- * ID Description
- *
- * 41 GPS Time
- * 44 Satellite selection, PDOP, mode
- * 46 Receiver health
- * 4B Machine code/status
- * 4C Report operating parameters (debug only)
- * 4F UTC correction data (used to get leap second warnings)
- * 55 I/O options (debug only)
- *
- * All others are accepted but ignored.
- *
- */
-
-#define PI 3.1415926535898 /* lots of sig figs */
-#define D2R PI/180.0
-
-/*-------------------------------------------------------------------
- * sendcmd, sendbyte, sendetx, sendflt, sendint implement the command
- * interface to the receiver.
- *
- * CAVEAT: the sendflt, sendint routines are byte order dependend and
- * float implementation dependend - these must be converted to portable
- * versions !
- *
- * CURRENT LIMITATION: float implementation. This runs only on systems
- * with IEEE754 floats as native floats
- */
-
-typedef struct trimble
-{
- u_long last_msg; /* last message received */
- u_char qtracking; /* query tracking status */
- u_long ctrack; /* current tracking set */
- u_long ltrack; /* last tracking set */
-} trimble_t;
-
-union uval {
- u_char bd[8];
- int iv;
- float fv;
- double dv;
-};
-
-struct txbuf
-{
- short idx; /* index to first unused byte */
- u_char *txt; /* pointer to actual data buffer */
-};
-
-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
-sendcmd(
- struct txbuf *buf,
- int c
- )
-{
- buf->txt[0] = DLE;
- buf->txt[1] = (u_char)c;
- buf->idx = 2;
-}
-
-void
-sendbyte(
- struct txbuf *buf,
- int b
- )
-{
- if (b == DLE)
- buf->txt[buf->idx++] = DLE;
- buf->txt[buf->idx++] = (u_char)b;
-}
-
-void
-sendetx(
- struct txbuf *buf,
- struct parseunit *parse
- )
-{
- buf->txt[buf->idx++] = DLE;
- buf->txt[buf->idx++] = ETX;
-
- if (write(parse->generic->io.fd, buf->txt, (unsigned long)buf->idx) != buf->idx)
- {
- ERR(ERR_BADIO)
- msyslog(LOG_ERR, "PARSE receiver #%d: sendetx: failed to send cmd to clock: %m", CLK_UNIT(parse->peer));
- }
- else
- {
-#ifdef DEBUG
- if (debug > 2)
- {
- char buffer[256];
-
- mkreadable(buffer, sizeof(buffer), (char *)buf->txt, (unsigned)buf->idx, 1);
- printf("PARSE receiver #%d: transmitted message (%d bytes) >%s<\n",
- CLK_UNIT(parse->peer),
- buf->idx, buffer);
- }
-#endif
- clear_err(parse, ERR_BADIO);
- }
-}
-
-void
-sendint(
- struct txbuf *buf,
- int a
- )
-{
- /* send 16bit int, msbyte first */
- sendbyte(buf, (u_char)((a>>8) & 0xff));
- sendbyte(buf, (u_char)(a & 0xff));
-}
-
-void
-sendflt(
- struct txbuf *buf,
- double a
- )
-{
- int i;
- union uval uval;
-
- uval.fv = a;
-#ifdef WORDS_BIGENDIAN
- for (i=0; i<=3; i++)
-#else
- for (i=3; i>=0; i--)
-#endif
- sendbyte(buf, uval.bd[i]);
-}
-
-#define TRIM_POS_OPT 0x13 /* output position with high precision */
-#define TRIM_TIME_OPT 0x03 /* use UTC time stamps, on second */
-
-/*--------------------------------------------------
- * trimble TSIP setup routine
- */
-static int
-trimbletsip_setup(
- struct parseunit *parse,
- const char *reason
- )
-{
- u_char buffer[256];
- struct txbuf buf;
-
- buf.txt = buffer;
-
- sendcmd(&buf, CMD_CVERSION); /* request software versions */
- sendetx(&buf, parse);
-
- sendcmd(&buf, CMD_COPERPARAM); /* set operating parameters */
- sendbyte(&buf, 4); /* static */
- sendflt(&buf, 5.0*D2R); /* elevation angle mask = 10 deg XXX */
- sendflt(&buf, 4.0); /* s/n ratio mask = 6 XXX */
- sendflt(&buf, 12.0); /* PDOP mask = 12 */
- sendflt(&buf, 8.0); /* PDOP switch level = 8 */
- sendetx(&buf, parse);
-
- sendcmd(&buf, CMD_CMODESEL); /* fix mode select */
- sendbyte(&buf, 0); /* automatic */
- sendetx(&buf, parse);
-
- sendcmd(&buf, CMD_CMESSAGE); /* request system message */
- sendetx(&buf, parse);
-
- sendcmd(&buf, CMD_CSUPER); /* superpacket fix */
- sendbyte(&buf, 0x2); /* binary mode */
- sendetx(&buf, parse);
-
- sendcmd(&buf, CMD_CIOOPTIONS); /* set I/O options */
- sendbyte(&buf, TRIM_POS_OPT); /* position output */
- sendbyte(&buf, 0x00); /* no velocity output */
- sendbyte(&buf, TRIM_TIME_OPT); /* UTC, compute on seconds */
- sendbyte(&buf, 0x00); /* no raw measurements */
- sendetx(&buf, parse);
-
- sendcmd(&buf, CMD_CUTCPARAM); /* request UTC correction data */
- sendetx(&buf, parse);
-
- NLOG(NLOG_CLOCKINFO)
- ERR(ERR_BADIO)
- msyslog(LOG_ERR, "PARSE receiver #%d: trimbletsip_setup: RECEIVER RE-INITIALIZED (%s)", CLK_UNIT(parse->peer), reason);
-
- return 0;
-}
-
-/*--------------------------------------------------
- * TRIMBLE TSIP check routine
- */
-static void
-trimble_check(
- struct peer *peer
- )
-{
- struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr;
- trimble_t *t = parse->localdata;
- u_char buffer[256];
- struct txbuf buf;
- buf.txt = buffer;
-
- if (t)
- {
- 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)
- {
- u_long oldsats = t->ltrack & ~t->ctrack;
-
- t->qtracking = 0;
- t->ltrack = t->ctrack;
-
- if (oldsats)
- {
- int 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);
- }
-
- sendcmd(&buf, CMD_CSTATTRACK);
- sendbyte(&buf, 0x00); /* current tracking set */
- sendetx(&buf, parse);
- }
-}
-
-/*--------------------------------------------------
- * TRIMBLE TSIP end routine
- */
-static void
-trimbletsip_end(
- struct parseunit *parse
- )
-{ trimble_t *t = parse->localdata;
-
- if (t)
- {
- free(t);
- parse->localdata = (void *)0;
- }
- parse->peer->nextaction = 0;
- parse->peer->action = (void (*) P((struct peer *)))0;
-}
-
-/*--------------------------------------------------
- * TRIMBLE TSIP init routine
- */
-static int
-trimbletsip_init(
- struct parseunit *parse
- )
-{
-#if defined(VEOL) || defined(VEOL2)
-#ifdef HAVE_TERMIOS
- struct termios tio; /* NEEDED FOR A LONG TIME ! */
-#endif
-#ifdef HAVE_SYSV_TTYS
- struct termio tio; /* NEEDED FOR A LONG TIME ! */
-#endif
- /*
- * allocate local data area
- */
- if (!parse->localdata)
- {
- trimble_t *t;
-
- t = (trimble_t *)(parse->localdata = emalloc(sizeof(trimble_t)));
-
- if (t)
- {
- memset((char *)t, 0, sizeof(trimble_t));
- t->last_msg = current_time;
- }
- }
-
- parse->peer->action = trimble_check;
- parse->peer->nextaction = current_time;
-
- /*
- * configure terminal line for ICANON mode with VEOL characters
- */
- if (TTY_GETATTR(parse->generic->io.fd, &tio) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: trimbletsip_init: tcgetattr(%d, &tio): %m", CLK_UNIT(parse->peer), parse->generic->io.fd);
- return 0;
- }
- else
- {
- if ((parse_clockinfo[CLK_TYPE(parse->peer)].cl_lflag & ICANON))
- {
-#ifdef VEOL
- tio.c_cc[VEOL] = ETX;
-#endif
-#ifdef VEOL2
- tio.c_cc[VEOL2] = DLE;
-#endif
- }
-
- if (TTY_SETATTR(parse->generic->io.fd, &tio) == -1)
- {
- msyslog(LOG_ERR, "PARSE receiver #%d: trimbletsip_init: tcsetattr(%d, &tio): %m", CLK_UNIT(parse->peer), parse->generic->io.fd);
- return 0;
- }
- }
-#endif
- return trimbletsip_setup(parse, "initial startup");
-}
-
-/*------------------------------------------------------------
- * trimbletsip_event - handle Trimble events
- * simple evente handler - attempt to re-initialize receiver
- */
-static void
-trimbletsip_event(
- struct parseunit *parse,
- int event
- )
-{
- switch (event)
- {
- case CEVNT_BADREPLY: /* reset on garbled input */
- case CEVNT_TIMEOUT: /* reset on no input */
- (void)trimbletsip_setup(parse, "event BAD_REPLY/TIMEOUT");
- break;
-
- default: /* ignore */
- break;
- }
-}
-
-/*
- * getflt, getint convert fields in the incoming data into the
- * appropriate type of item
- *
- * CAVEAT: these routines are currently definitely byte order dependent
- * and assume Representation(float) == IEEE754
- * These functions MUST be converted to portable versions (especially
- * converting the float representation into ntp_fp formats in order
- * to avoid floating point operations at all!
- */
-
-static float
-getflt(
- u_char *bp
- )
-{
- union uval uval;
-
-#ifdef WORDS_BIGENDIAN
- uval.bd[0] = *bp++;
- uval.bd[1] = *bp++;
- uval.bd[2] = *bp++;
- uval.bd[3] = *bp;
-#else /* ! WORDS_BIGENDIAN */
- uval.bd[3] = *bp++;
- uval.bd[2] = *bp++;
- uval.bd[1] = *bp++;
- uval.bd[0] = *bp;
-#endif /* ! WORDS_BIGENDIAN */
- return uval.fv;
-}
-
-static double
-getdbl(
- u_char *bp
- )
-{
- union uval uval;
-
-#ifdef WORDS_BIGENDIAN
- uval.bd[0] = *bp++;
- uval.bd[1] = *bp++;
- uval.bd[2] = *bp++;
- uval.bd[3] = *bp++;
- uval.bd[4] = *bp++;
- uval.bd[5] = *bp++;
- uval.bd[6] = *bp++;
- uval.bd[7] = *bp;
-#else /* ! WORDS_BIGENDIAN */
- uval.bd[7] = *bp++;
- uval.bd[6] = *bp++;
- uval.bd[5] = *bp++;
- uval.bd[4] = *bp++;
- uval.bd[3] = *bp++;
- uval.bd[2] = *bp++;
- uval.bd[1] = *bp++;
- uval.bd[0] = *bp;
-#endif /* ! WORDS_BIGENDIAN */
- return uval.dv;
-}
-
-static int
-getshort(
- unsigned char *p
- )
-{
- return get_msb_short(&p);
-}
-
-/*--------------------------------------------------
- * trimbletsip_message - process trimble messages
- */
-#define RTOD (180.0 / 3.1415926535898)
-#define mb(_X_) (buffer[2+(_X_)]) /* shortcut for buffer access */
-
-static void
-trimbletsip_message(
- struct parseunit *parse,
- parsetime_t *parsetime
- )
-{
- unsigned char *buffer = parsetime->parse_msg;
- unsigned int size = parsetime->parse_msglen;
-
- if ((size < 4) ||
- (buffer[0] != DLE) ||
- (buffer[size-1] != ETX) ||
- (buffer[size-2] != DLE))
- {
-#ifdef DEBUG
- if (debug > 2) {
- int i;
-
- printf("TRIMBLE BAD packet, size %d:\n ", size);
- for (i = 0; i < size; i++) {
- printf ("%2.2x, ", buffer[i]&0xff);
- if (i%16 == 15) printf("\n\t");
- }
- printf("\n");
- }
-#endif
- return;
- }
- else
- {
- int var_flag;
- trimble_t *tr = parse->localdata;
- unsigned int cmd = buffer[1];
- char pbuffer[200];
- char *t = pbuffer;
- cmd_info_t *s;
-
-#ifdef DEBUG
- if (debug > 3) {
- int i;
-
- printf("TRIMBLE packet 0x%02x, size %d:\n ", cmd, size);
- for (i = 0; i < size; i++) {
- printf ("%2.2x, ", buffer[i]&0xff);
- if (i%16 == 15) printf("\n\t");
- }
- printf("\n");
- }
-#endif
-
- if (tr)
- tr->last_msg = current_time;
-
- s = trimble_convert(cmd, trimble_rcmds);
-
- if (s)
- {
- sprintf(t, "%s=\"", s->varname);
- }
- else
- {
- printf("TRIMBLE unknown command 0x%02x\n", cmd);
- return;
- }
-
- var_flag = s->varmode;
-
- t += strlen(t);
-
- 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)));
- break;
-
- case CMD_RBEST4:
- strcpy(t, "mode: ");
- t += strlen(t);
- switch (mb(0) & 0xF)
- {
- default:
- sprintf(t, "0x%x", mb(0) & 0x7);
- break;
-
- case 1:
- strcat(t, "0D");
- break;
-
- case 3:
- strcat(t, "2D");
- break;
-
- case 4:
- strcat(t, "3D");
- break;
- }
- t += strlen(t);
- if (mb(0) & 0x10)
- strcpy(t, "-MANUAL, ");
- else
- strcpy(t, "-AUTO, ");
- t += strlen(t);
-
- sprintf(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)),
- getflt((unsigned char *)&mb(13)),
- getflt((unsigned char *)&mb(17)));
-
- break;
-
- case CMD_RVERSION:
- sprintf(t, "%d.%d (%d/%d/%d)",
- mb(0)&0xff, mb(1)&0xff, 1900+(mb(4)&0xff), mb(2)&0xff, mb(3)&0xff);
- break;
-
- case CMD_RRECVHEALTH:
- {
- static const char *msgs[] =
- {
- "Battery backup failed",
- "Signal processor error",
- "Alignment error, channel or chip 1",
- "Alignment error, channel or chip 2",
- "Antenna feed line fault",
- "Excessive ref freq. error",
- "<BIT 6>",
- "<BIT 7>"
- };
-
- int i, bits;
-
- switch (mb(0) & 0xFF)
- {
- default:
- sprintf(t, "illegal value 0x%02x", mb(0) & 0xFF);
- break;
- case 0x00:
- strcpy(t, "doing position fixes");
- break;
- case 0x01:
- strcpy(t, "no GPS time yet");
- break;
- case 0x03:
- strcpy(t, "PDOP too high");
- break;
- case 0x08:
- strcpy(t, "no usable satellites");
- break;
- case 0x09:
- strcpy(t, "only ONE usable satellite");
- break;
- case 0x0A:
- strcpy(t, "only TWO usable satellites");
- break;
- case 0x0B:
- strcpy(t, "only THREE usable satellites");
- break;
- case 0x0C:
- strcpy(t, "the chosen satellite is unusable");
- break;
- }
-
- t += strlen(t);
-
- bits = mb(1) & 0xFF;
-
- for (i = 0; i < 8; i++)
- if (bits & (0x1<<i))
- {
- sprintf(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);
- break;
-
- case CMD_RMACHSTAT:
- {
- static const char *msgs[] =
- {
- "Synthesizer Fault",
- "Battery Powered Time Clock Fault",
- "A-to-D Converter Fault",
- "The almanac stored in the receiver is not complete and current",
- "<BIT 4>",
- "<BIT 5",
- "<BIT 6>",
- "<BIT 7>"
- };
-
- int i, bits;
-
- sprintf(t, "machine id 0x%02x", mb(0) & 0xFF);
- t += strlen(t);
-
- bits = mb(1) & 0xFF;
-
- for (i = 0; i < 8; i++)
- if (bits & (0x1<<i))
- {
- sprintf(t, ", %s", msgs[i]);
- t += strlen(t);
- }
-
- sprintf(t, ", Superpackets %ssupported", (mb(2) & 0xFF) ? "" :"un" );
- }
- break;
-
- case CMD_ROPERPARAM:
- sprintf(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;
-
- case CMD_RUTCPARAM:
- {
- float t0t = getflt((unsigned char *)&mb(14));
- short wnt = getshort((unsigned char *)&mb(18));
- short dtls = getshort((unsigned char *)&mb(12));
- short wnlsf = getshort((unsigned char *)&mb(20));
- short dn = getshort((unsigned char *)&mb(22));
- short dtlsf = getshort((unsigned char *)&mb(24));
-
- if ((int)t0t != 0)
- {
- mk_utcinfo(t, wnt, wnlsf, dn, dtls, dtlsf);
- }
- else
- {
- strcpy(t, "<NO UTC DATA>");
- }
- }
- break;
-
- case CMD_RSAT1BIAS:
- sprintf(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",
- mb(0), mb(1), mb(2), mb(3));
- if (mb(0) != TRIM_POS_OPT ||
- mb(2) != TRIM_TIME_OPT)
- {
- (void)trimbletsip_setup(parse, "bad io options");
- }
- }
- break;
-
- case CMD_RSPOSXYZ:
- {
- double x = getflt((unsigned char *)&mb(0));
- double y = getflt((unsigned char *)&mb(4));
- double z = getflt((unsigned char *)&mb(8));
- double f = getflt((unsigned char *)&mb(12));
-
- if (f > 0.0)
- sprintf(t, "x= %.1fm, y= %.1fm, z= %.1fm, time_of_fix= %f sec",
- x, y, z,
- f);
- else
- return;
- }
- break;
-
- case CMD_RSLLAPOS:
- {
- double lat = getflt((unsigned char *)&mb(0));
- double lng = getflt((unsigned char *)&mb(4));
- double f = getflt((unsigned char *)&mb(12));
-
- if (f > 0.0)
- sprintf(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)));
- else
- return;
- }
- break;
-
- case CMD_RDOUBLEXYZ:
- {
- 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",
- x, y, z);
- }
- break;
-
- case CMD_RDOUBLELLA:
- {
- double lat = getdbl((unsigned char *)&mb(0));
- double lng = getdbl((unsigned char *)&mb(8));
- sprintf(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)));
- }
- break;
-
- case CMD_RALLINVIEW:
- {
- int i, sats;
-
- strcpy(t, "mode: ");
- t += strlen(t);
- switch (mb(0) & 0x7)
- {
- default:
- sprintf(t, "0x%x", mb(0) & 0x7);
- break;
-
- case 3:
- strcat(t, "2D");
- break;
-
- case 4:
- strcat(t, "3D");
- break;
- }
- t += strlen(t);
- if (mb(0) & 0x8)
- strcpy(t, "-MANUAL, ");
- else
- strcpy(t, "-AUTO, ");
- t += strlen(t);
-
- sats = (mb(0)>>4) & 0xF;
-
- sprintf(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)),
- getflt((unsigned char *)&mb(13)),
- sats, (sats == 1) ? "" : "s");
- t += strlen(t);
-
- for (i=0; i < sats; i++)
- {
- sprintf(t, "%s%02d", i ? ", " : "", mb(17+i));
- t += strlen(t);
- if (tr)
- tr->ctrack |= (1 << (mb(17+i)-1));
- }
-
- if (tr)
- { /* mark for tracking status query */
- tr->qtracking = 1;
- }
- }
- break;
-
- case CMD_RSTATTRACK:
- {
- sprintf(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>");
- var_flag &= ~DEF;
- }
- else
- {
- sprintf(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),
- getflt((unsigned char *)&mb(4)),
- getflt((unsigned char *)&mb(12)) * RTOD,
- getflt((unsigned char *)&mb(16)) * RTOD);
- t += strlen(t);
- if (mb(20))
- {
- var_flag &= ~DEF;
- strcpy(t, ", OLD");
- }
- t += strlen(t);
- if (mb(22))
- {
- if (mb(22) == 1)
- strcpy(t, ", BAD PARITY");
- else
- if (mb(22) == 2)
- strcpy(t, ", BAD EPH HEALTH");
- }
- t += strlen(t);
- if (mb(23))
- strcpy(t, ", collecting data");
- }
- }
- break;
-
- default:
- strcpy(t, "<UNDECODED>");
- break;
- }
- strcat(t,"\"");
- set_var(&parse->kv, pbuffer, sizeof(pbuffer), var_flag);
- }
-}
-
-
-/**============================================================
- ** RAWDCF support
- **/
-
-/*--------------------------------------------------
- * rawdcf_init_1 - set up modem lines for RAWDCF receivers
- * SET DTR line
- */
-#if defined(TIOCMSET) && (defined(TIOCM_DTR) || defined(CIOCM_DTR))
-static int
-rawdcf_init_1(
- struct parseunit *parse
- )
-{
- /* fixed 2000 for using with Linux by Wolfram Pienkoss <wp@bszh.de> */
- /*
- * You can use the RS232 to supply the power for a DCF77 receiver.
- * Here a voltage between the DTR and the RTS line is used. Unfortunately
- * the name has changed from CIOCM_DTR to TIOCM_DTR recently.
- */
- int sl232;
-
- if (ioctl(parse->generic->io.fd, TIOCMGET, (caddr_t)&sl232) == -1)
- {
- msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_1: WARNING: ioctl(fd, TIOCMGET, [C|T]IOCM_DTR): %m", CLK_UNIT(parse->peer));
- return 0;
- }
-
-#ifdef TIOCM_DTR
- sl232 = (sl232 & ~TIOCM_RTS) | TIOCM_DTR; /* turn on DTR, clear RTS for power supply */
-#else
- sl232 = (sl232 & ~CIOCM_RTS) | CIOCM_DTR; /* turn on DTR, clear RTS for power supply */
-#endif
-
- if (ioctl(parse->generic->io.fd, TIOCMSET, (caddr_t)&sl232) == -1)
- {
- msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_1: WARNING: ioctl(fd, TIOCMSET, [C|T]IOCM_DTR): %m", CLK_UNIT(parse->peer));
- }
- return 0;
-}
-#else
-static int
-rawdcfdtr_init_1(
- struct parseunit *parse
- )
-{
- msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_1: WARNING: OS interface incapable of setting DTR to power DCF modules", CLK_UNIT(parse->peer));
- return 0;
-}
-#endif /* DTR initialisation type */
-
-/*--------------------------------------------------
- * rawdcf_init_2 - set up modem lines for RAWDCF receivers
- * CLR DTR line, SET RTS line
- */
-#if defined(TIOCMSET) && (defined(TIOCM_RTS) || defined(CIOCM_RTS))
-static int
-rawdcf_init_2(
- struct parseunit *parse
- )
-{
- /* fixed 2000 for using with Linux by Wolfram Pienkoss <wp@bszh.de> */
- /*
- * You can use the RS232 to supply the power for a DCF77 receiver.
- * Here a voltage between the DTR and the RTS line is used. Unfortunately
- * the name has changed from CIOCM_DTR to TIOCM_DTR recently.
- */
- int sl232;
-
- if (ioctl(parse->generic->io.fd, TIOCMGET, (caddr_t)&sl232) == -1)
- {
- msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_2: WARNING: ioctl(fd, TIOCMGET, [C|T]IOCM_RTS): %m", CLK_UNIT(parse->peer));
- return 0;
- }
-
-#ifdef TIOCM_RTS
- sl232 = (sl232 & ~TIOCM_DTR) | TIOCM_RTS; /* turn on RTS, clear DTR for power supply */
-#else
- sl232 = (sl232 & ~CIOCM_DTR) | CIOCM_RTS; /* turn on RTS, clear DTR for power supply */
-#endif
-
- if (ioctl(parse->generic->io.fd, TIOCMSET, (caddr_t)&sl232) == -1)
- {
- msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_2: WARNING: ioctl(fd, TIOCMSET, [C|T]IOCM_RTS): %m", CLK_UNIT(parse->peer));
- }
- return 0;
-}
-#else
-static int
-rawdcf_init_2(
- struct parseunit *parse
- )
-{
- msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_2: WARNING: OS interface incapable of setting RTS to power DCF modules", CLK_UNIT(parse->peer));
- return 0;
-}
-#endif /* DTR initialisation type */
-
-#else /* defined(REFCLOCK) && defined(PARSE) */
-int refclock_parse_bs;
-#endif /* defined(REFCLOCK) && defined(PARSE) */
-
-/*
- * History:
- *
- * refclock_parse.c,v
- * Revision 4.36 1999/11/28 17:18:20 kardel
- * disabled burst mode
- *
- * Revision 4.35 1999/11/28 09:14:14 kardel
- * RECON_4_0_98F
- *
- * Revision 4.34 1999/05/14 06:08:05 kardel
- * store current_time in a suitable container (u_long)
- *
- * Revision 4.33 1999/05/13 21:48:38 kardel
- * double the no response timeout interval
- *
- * Revision 4.32 1999/05/13 20:09:13 kardel
- * complain only about missing polls after a full poll interval
- *
- * Revision 4.31 1999/05/13 19:59:32 kardel
- * add clock type 16 for RTS set DTR clr in RAWDCF
- *
- * Revision 4.30 1999/02/28 20:36:43 kardel
- * fixed printf fmt
- *
- * Revision 4.29 1999/02/28 19:58:23 kardel
- * updated copyright information
- *
- * Revision 4.28 1999/02/28 19:01:50 kardel
- * improved debug out on sent Meinberg messages
- *
- * Revision 4.27 1999/02/28 18:05:55 kardel
- * no linux/ppsclock.h stuff
- *
- * Revision 4.26 1999/02/28 15:27:27 kardel
- * wharton clock integration
- *
- * Revision 4.25 1999/02/28 14:04:46 kardel
- * added missing double quotes to UTC information string
- *
- * Revision 4.24 1999/02/28 12:06:50 kardel
- * (parse_control): using gmprettydate instead of prettydate()
- * (mk_utcinfo): new function for formatting GPS derived UTC information
- * (gps16x_message): changed to use mk_utcinfo()
- * (trimbletsip_message): changed to use mk_utcinfo()
- * ignoring position information in unsynchronized mode
- * (parse_start): augument linux support for optional ASYNC_LOW_LATENCY
- *
- * Revision 4.23 1999/02/23 19:47:53 kardel
- * fixed #endifs
- * (stream_receive): fixed formats
- *
- * Revision 4.22 1999/02/22 06:21:02 kardel
- * use new autoconfig symbols
- *
- * Revision 4.21 1999/02/21 12:18:13 kardel
- * 4.91f reconcilation
- *
- * Revision 4.20 1999/02/21 10:53:36 kardel
- * initial Linux PPSkit version
- *
- * Revision 4.19 1999/02/07 09:10:45 kardel
- * clarify STREAMS mitigation rules in comment
- *
- * Revision 4.18 1998/12/20 23:45:34 kardel
- * fix types and warnings
- *
- * Revision 4.17 1998/11/15 21:24:51 kardel
- * cannot access mbg_ routines when CLOCK_MEINBERG
- * is not defined
- *
- * Revision 4.16 1998/11/15 20:28:17 kardel
- * Release 4.0.73e13 reconcilation
- *
- * Revision 4.15 1998/08/22 21:56:08 kardel
- * fixed IO handling for non-STREAM IO
- *
- * Revision 4.14 1998/08/16 19:00:48 kardel
- * (gps16x_message): reduced UTC parameter information (dropped A0,A1)
- * made uval a local variable (killed one of the last globals)
- * (sendetx): added logging of messages when in debug mode
- * (trimble_check): added periodic checks to facilitate re-initialization
- * (trimbletsip_init): made use of EOL character if in non-kernel operation
- * (trimbletsip_message): extended message interpretation
- * (getdbl): fixed data conversion
- *
- * Revision 4.13 1998/08/09 22:29:13 kardel
- * Trimble TSIP support
- *
- * Revision 4.12 1998/07/11 10:05:34 kardel
- * Release 4.0.73d reconcilation
- *
- * Revision 4.11 1998/06/14 21:09:42 kardel
- * Sun acc cleanup
- *
- * Revision 4.10 1998/06/13 12:36:45 kardel
- * signed/unsigned, name clashes
- *
- * Revision 4.9 1998/06/12 15:30:00 kardel
- * prototype fixes
- *
- * Revision 4.8 1998/06/12 11:19:42 kardel
- * added direct input processing routine for refclocks in
- * order to avaiod that single character io gobbles up all
- * receive buffers and drops input data. (Problem started
- * with fast machines so a character a buffer was possible
- * one of the few cases where faster machines break existing
- * allocation algorithms)
- *
- * Revision 4.7 1998/06/06 18:35:20 kardel
- * (parse_start): added BURST mode initialisation
- *
- * Revision 4.6 1998/05/27 06:12:46 kardel
- * RAWDCF_BASEDELAY default added
- * old comment removed
- * casts for ioctl()
- *
- * Revision 4.5 1998/05/25 22:05:09 kardel
- * RAWDCF_SETDTR option removed
- * clock type 14 attempts to set DTR for
- * power supply of RAWDCF receivers
- *
- * Revision 4.4 1998/05/24 16:20:47 kardel
- * updated comments referencing Meinberg clocks
- * added RAWDCF clock with DTR set option as type 14
- *
- * Revision 4.3 1998/05/24 10:48:33 kardel
- * calibrated CONRAD RAWDCF default fudge factor
- *
- * Revision 4.2 1998/05/24 09:59:35 kardel
- * corrected version information (ntpq support)
- *
- * Revision 4.1 1998/05/24 09:52:31 kardel
- * use fixed format only (new IO model)
- * output debug to stdout instead of msyslog()
- * don't include >"< in ASCII output in order not to confuse
- * ntpq parsing
- *
- * Revision 4.0 1998/04/10 19:52:11 kardel
- * Start 4.0 release version numbering
- *
- * Revision 1.2 1998/04/10 19:28:04 kardel
- * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
- * derived from 3.105.1.2 from V3 tree
- *
- * Revision information 3.1 - 3.105 from log deleted 1998/04/10 kardel
- *
- */
OpenPOWER on IntegriCloud