/*
* /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