/ntp-4.2.6p5/ntpd/refclock_parse.c
C | 6158 lines | 5120 code | 326 blank | 712 comment | 147 complexity | 7da9ac33c84e1bc9693c191d86bdcc5b MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, LGPL-3.0
Large files files are truncated, but you can click here to view the full file
- /*
- * /src/NTP/REPOSITORY/ntp4-dev/ntpd/refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A
- *
- * refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A
- *
- * generic reference clock driver for several DCF/GPS/MSF/... receivers
- *
- * PPS notes:
- * On systems that support PPSAPI (RFC2783) PPSAPI is the
- * preferred interface.
- *
- * Optionally make use of a STREAMS module for input processing where
- * available and configured. This STREAMS module reduces the time
- * stamp latency for serial and PPS events.
- * Currently the STREAMS module is only available for Suns running
- * SunOS 4.x and SunOS5.x.
- *
- * Copyright (c) 1995-2009 by Frank Kardel <kardel <AT> ntp.org>
- * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
- #ifdef HAVE_CONFIG_H
- # include "config.h"
- #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)
- * - WHARTON 400A Series clock (DCF)
- *
- * - Meinberg GPS166/GPS167 (GPS)
- * - Trimble (TSIP and TAIP protocol) (GPS)
- *
- * - RCC8000 MSF Receiver (MSF)
- * - 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 "ntp_string.h"
- #include <stdio.h>
- #include <ctype.h>
- #ifndef TM_IN_SYS_TIME
- # include <time.h>
- #endif
- #ifdef HAVE_UNISTD_H
- # include <unistd.h>
- #endif
- #if !defined(STREAM) && !defined(HAVE_SYSV_TTYS) && !defined(HAVE_BSD_TTYS) && !defined(HAVE_TERMIOS)
- # include "Bletch: Define one of {STREAM,HAVE_SYSV_TTYS,HAVE_TERMIOS}"
- #endif
- #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 HAVE_PPSAPI
- # include "ppsapi_timepps.h"
- # include "refclock_atom.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
- #define BUFFER_SIZE(_BUF, _PTR) ((_BUF) + sizeof(_BUF) - (_PTR))
- #define BUFFER_SIZES(_BUF, _PTR, _SZ) ((_BUF) + (_SZ) - (_PTR))
- /*
- * document type of PPS interfacing - copy of ifdef mechanism in local_input()
- */
- #undef PPS_METHOD
- #ifdef HAVE_PPSAPI
- #define PPS_METHOD "PPS API"
- #else
- #ifdef TIOCDCDTIMESTAMP
- #define PPS_METHOD "TIOCDCDTIMESTAMP"
- #else /* TIOCDCDTIMESTAMP */
- #if defined(HAVE_STRUCT_PPSCLOCKEV) && (defined(HAVE_CIOGETEV) || defined(HAVE_TIOCGPPSEV))
- #ifdef HAVE_CIOGETEV
- #define PPS_METHOD "CIOGETEV"
- #endif
- #ifdef HAVE_TIOCGPPSEV
- #define PPS_METHOD "TIOCGPPSEV"
- #endif
- #endif
- #endif /* TIOCDCDTIMESTAMP */
- #endif /* HAVE_PPSAPI */
- #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"
- #include "recvbuff.h"
- static char rcsid[] = "refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A+POWERUPTRUST";
- /**===========================================================================
- ** external interface to ntp mechanism
- **/
- static int parse_start (int, struct peer *);
- static void parse_shutdown (int, struct peer *);
- static void parse_poll (int, struct peer *);
- static void parse_control (int, struct refclockstat *, struct refclockstat *, struct peer *);
- struct refclock refclock_parse = {
- parse_start,
- parse_shutdown,
- parse_poll,
- parse_control,
- noentry,
- noentry,
- NOFLAGS
- };
- /*
- * Definitions
- */
- #define MAXUNITS 4 /* maximum number of "PARSE" units permitted */
- #define PARSEDEVICE "/dev/refclock-%d" /* device to open %d is unit number */
- #define PARSEPPSDEVICE "/dev/refclockpps-%d" /* optional pps device to open %d is unit number */
- #undef ABS
- #define ABS(_X_) (((_X_) < 0) ? -(_X_) : (_X_))
- #define PARSE_HARDPPS_DISABLE 0
- #define PARSE_HARDPPS_ENABLE 1
- /**===========================================================================
- ** function vector for dynamically binding io handling mechanism
- **/
- struct parseunit; /* to keep inquiring minds happy */
- typedef struct bind
- {
- const char *bd_description; /* name of type of binding */
- int (*bd_init) (struct parseunit *); /* initialize */
- void (*bd_end) (struct parseunit *); /* end */
- int (*bd_setcs) (struct parseunit *, parsectl_t *); /* set character size */
- int (*bd_disable) (struct parseunit *); /* disable */
- int (*bd_enable) (struct parseunit *); /* enable */
- int (*bd_getfmt) (struct parseunit *, parsectl_t *); /* get format */
- int (*bd_setfmt) (struct parseunit *, parsectl_t *); /* setfmt */
- int (*bd_timecode) (struct parseunit *, parsectl_t *); /* get time code */
- void (*bd_receive) (struct recvbuf *); /* receive operation */
- int (*bd_io_input) (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_)
- /*
- * special handling flags
- */
- #define PARSE_F_PPSONSECOND 0x00000001 /* PPS pulses are on second */
- #define PARSE_F_POWERUPTRUST 0x00000100 /* POWERUP state ist trusted for */
- /* trusttime after SYNC was seen */
- /**===========================================================================
- ** 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 maxunsync; /* max time in seconds a receiver is trusted after loosing synchronisation */
- double ppsphaseadjust; /* phase adjustment of PPS time stamp */
- u_long lastmissed; /* time (ntp) when poll didn't get data (powerup heuristic) */
- u_long ppsserial; /* magic cookie for ppsclock serials (avoids stale ppsclock data) */
- int ppsfd; /* fd to ise for PPS io */
- #ifdef HAVE_PPSAPI
- int hardppsstate; /* current hard pps state */
- struct refclock_atom atom; /* PPSAPI structure */
- #endif
- parsetime_t timedata; /* last (parse module) data */
- void *localdata; /* optional local, receiver-specific data */
- unsigned long localstate; /* private local state */
- struct errorinfo errors[ERR_CNT]; /* error state table for suppressing excessive error messages */
- 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 (struct parseunit *);
- static void poll_poll (struct peer *);
- static int poll_init (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_LCLDATA 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_LCLDATA
- #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|CSTOPB)
- #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 (struct parseunit *, parsetime_t *);
- static int gps16x_poll_init (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)"
- /* Gude Analog- und Digitalsystem GmbH 'Expert mouseCLOCK USB v2.0' */
- #define GUDE_EMC_USB_V20_SPEED (B4800)
- #define GUDE_EMC_USB_V20_BASEDELAY 0.425 /* USB serial<->USB converter FTDI232R */
- #define GUDE_EMC_USB_V20_DESCRIPTION "RAW DCF77 CODE (Expert mouseCLOCK USB v2.0)"
- /*
- * TimeBrick receiver
- */
- #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 (struct parseunit *);
- #define RAWDCFDTRSET_DESCRIPTION "RAW DCF77 CODE (DTR SET/RTS CLR)"
- #define RAWDCFDTRSET75_DESCRIPTION "RAW DCF77 CODE (DTR SET/RTS CLR @ 75 baud)"
- #define RAWDCFDTRSET_INIT rawdcf_init_1
- /*
- * RAWDCF receivers that need to be powered from
- * DTR CLR and RTS SET
- */
- static int rawdcf_init_2 (struct parseunit *);
- #define RAWDCFDTRCLRRTSSET_DESCRIPTION "RAW DCF77 CODE (DTR CLR/RTS SET)"
- #define RAWDCFDTRCLRRTSSET75_DESCRIPTION "RAW DCF77 CODE (DTR CLR/RTS SET @ 75 baud)"
- #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 (struct parseunit *);
- static void trimbletaip_event (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 (struct parseunit *);
- static void trimbletsip_end (struct parseunit *);
- static void trimbletsip_message (struct parseunit *, parsetime_t *);
- static void trimbletsip_event (struct parseunit *, int);
- #define TRIMBLETSIP_IDLE_TIME (300) /* 5 minutes silence at most */
- #define TRIMBLE_RESET_HOLDOFF TRIMBLETSIP_IDLE_TIME
- #define TRIMBLETAIP_SPEED (B4800)
- #define TRIMBLETAIP_CFLAG (CS8|CREAD|CLOCAL)
- #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 (PPS interpretation, trust handling) */
- void (*cl_poll) (struct parseunit *); /* active poll routine */
- int (*cl_init) (struct parseunit *); /* active poll init routine */
- void (*cl_event) (struct parseunit *, int); /* special event handling (e.g. reset clock) */
- void (*cl_end) (struct parseunit *); /* active poll end routine */
- void (*cl_message) (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_LCLDATA,
- 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_LCLDATA,
- 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_LCLDATA,
- 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_LCLDATA,
- 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_LCLDATA,
- 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_LCLDATA,
- 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_LCLDATA,
- 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_LCLDATA,
- 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_LCLDATA,
- 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_LCLDATA,
- 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_LCLDATA, /* local data area for "poll" mechanism */
- 0, /* rootdelay */
- 11.0 /* bits */ / 9600, /* current offset by which the RS232
- time code is delayed from the actual time */
- 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_LCLDATA,
- 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_LCLDATA,
- 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
- },
- { /* mode 18 */
- MBG_FLAGS,
- NO_POLL,
- NO_INIT,
- NO_EVENT,
- GPS16X_END,
- GPS16X_MESSAGE,
- GPS16X_DATA,
- GPS16X_ROOTDELAY,
- GPS16X_BASEDELAY,
- GPS16X_ID,
- GPS16X_DESCRIPTION,
- GPS16X_FORMAT,
- GPS_TYPE,
- GPS16X_MAXUNSYNC,
- GPS16X_SPEED,
- GPS16X_CFLAG,
- GPS16X_IFLAG,
- GPS16X_OFLAG,
- GPS16X_LFLAG,
- GPS16X_SAMPLES,
- GPS16X_KEEP
- },
- { /* mode 19 */
- RAWDCF_FLAGS,
- NO_POLL,
- RAWDCF_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_LCLDATA,
- RAWDCF_ROOTDELAY,
- GUDE_EMC_USB_V20_BASEDELAY,
- DCF_A_ID,
- GUDE_EMC_USB_V20_DESCRIPTION,
- RAWDCF_FORMAT,
- DCF_TYPE,
- RAWDCF_MAXUNSYNC,
- GUDE_EMC_USB_V20_SPEED,
- RAWDCF_CFLAG,
- RAWDCF_IFLAG,
- RAWDCF_OFLAG,
- RAWDCF_LFLAG,
- RAWDCF_SAMPLES,
- RAWDCF_KEEP
- },
- { /* mode 20, like mode 14 but driven by 75 baud */
- RAWDCF_FLAGS,
- NO_POLL,
- RAWDCFDTRSET_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_LCLDATA,
- RAWDCF_ROOTDELAY,
- RAWDCF_BASEDELAY,
- DCF_A_ID,
- RAWDCFDTRSET75_DESCRIPTION,
- RAWDCF_FORMAT,
- DCF_TYPE,
- RAWDCF_MAXUNSYNC,
- B75,
- RAWDCF_CFLAG,
- RAWDCF_IFLAG,
- RAWDCF_OFLAG,
- RAWDCF_LFLAG,
- RAWDCF_SAMPLES,
- RAWDCF_KEEP
- },
- { /* mode 21, like mode 16 but driven by 75 baud
- - RAWDCF RTS set, DTR clr */
- RAWDCF_FLAGS,
- NO_POLL,
- RAWDCFDTRCLRRTSSET_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_LCLDATA,
- RAWDCF_ROOTDELAY,
- RAWDCF_BASEDELAY,
- DCF_A_ID,
- RAWDCFDTRCLRRTSSET75_DESCRIPTION,
- RAWDCF_FORMAT,
- DCF_TYPE,
- RAWDCF_MAXUNSYNC,
- B75,
- RAWDCF_CFLAG,
- RAWDCF_IFLAG,
- RAWDCF_OFLAG,
- RAWDCF_LFLAG,
- RAWDCF_SAMPLES,
- RAWDCF_KEEP
- },
- { /* mode 22 - like 2 with POWERUP trust */
- MBG_FLAGS | PARSE_F_POWERUPTRUST,
- NO_POLL,
- NO_INIT,
- NO_EVENT,
- NO_END,
- NO_MESSAGE,
- NO_LCLDATA,
- 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 23 - like 7 with POWERUP trust */
- MBG_FLAGS | PARSE_F_POWERUPTRUST,
- 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
- },
- };
- 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 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 (struct parseunit *, int);
- static void parse_process (struct parseunit *, parsetime_t *);
- static void clear_err (struct parseunit *, u_long);
- static int list_err (struct parseunit *, u_long);
- static char * l_mktime (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 = NULL;
- if (blen < 4)
- return NULL; /* 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
- {
- snprintf(buffer, blen, "\\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 (struct parseunit *);
- static int stream_init (struct parseunit *);
- static void stream_end (struct parseunit *);
- static int stream_enable (struct parseunit *);
- static int stream_disable (struct parseunit *);
- static int stream_setcs (struct parseunit *, parsectl_t *);
- static int stream_getfmt (struct parseunit *, parsectl_t *);
- static int stream_setfmt (struct parseunit *, parsectl_t *);
- static int stream_timecode (struct parseunit *, parsectl_t *);
- static void stream_receive (struct recvbuf *);
- #endif
-
- static int local_init (struct parseunit *);
- static void local_end (struct parseunit *);
- static int local_nop (struct parseunit *);
- static int local_setcs (struct parseunit *, parsectl_t *);
- static int local_getfmt (struct parseunit *, parsectl_t *);
- static int local_setfmt (struct parseunit *, parsectl_t *);
- static int local_timecode (struct parseunit *, parsectl_t *);
- static void local_receive (struct recvbuf *);
- static int local_input (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 pa…
Large files files are truncated, but you can click here to view the full file