refclock_leitch.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* Copyright (c) 1996 by Sun Microsystems, Inc.
* All Rights Reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* refclock_leitch - clock driver for the Leitch CSD-5300 Master Clock
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <ctype.h>
#include "ntpd.h"
#include "ntp_io.h"
#include "ntp_refclock.h"
#include "ntp_unixtime.h"
#if defined(HAVE_BSD_TTYS)
#include <sgtty.h>
#endif /* HAVE_BSD_TTYS */
#if defined(HAVE_SYSV_TTYS)
#include <termio.h>
#endif /* HAVE_SYSV_TTYS */
#if defined(HAVE_TERMIOS)
#include <termios.h>
#endif
#ifdef STREAM
#include <stropts.h>
#if defined(LEITCHCLK)
#endif /* LEITCHCLK */
#endif /* STREAM */
#if defined (LEITCHPPS)
#include <sys/ppsclock.h>
#endif /* LEITCHPPS */
#include "ntp_stdlib.h"
/*
* Driver for Leitch CSD-5300 Master Clock System
*
* COMMANDS:
* DATE: D <CR>
* TIME: T <CR>
* STATUS: S <CR>
* LOOP: L <CR>
*
* FORMAT:
* DATE: YYMMDD<CR>
* TIME: <CR>/HHMMSS <CR>/HHMMSS <CR>/HHMMSS <CR>/
* second bondaried on the stop bit of the <CR>
* second boundaries at '/' above.
* STATUS: G (good), D (diag fail), T (time not provided) or
* P (last phone update failed)
*/
#define LEITCH_DESCRIPTION "Leitch: CSD 5300 Master Clock System Driver"
#define leitch_send(A,M) \
if (debug) \
else \
#define STATE_IDLE 0
#define STATE_DATE 1
#define STATE_TIME1 2
#define STATE_TIME2 3
#define STATE_TIME3 4
extern struct event timerqueue[];
/*
* Imported from ntp_loopfilter module
*/
extern int fdpps; /* pps file descriptor */
/*
* Imported from ntpd module
*/
extern int debug; /* global debug flag */
/*
* LEITCH unit control structure
*/
struct leitchunit {
struct event leitchtimer;
struct refclockio leitchio;
short year;
short yearday;
short month;
short day;
short hour;
short second;
short minute;
short state;
};
/*
* Function prototypes
*/
static void leitch_init P((void));
static int leitch_start P((int, struct peer *));
static void leitch_shutdown P((int, struct peer *));
static void leitch_poll P((int, struct peer *));
#define leitch_buginfo noentry
static void leitch_receive P((struct recvbuf *));
static void leitch_process P((struct leitchunit *));
#if 0
static void leitch_timeout P((struct peer *));
#endif
static int days_per_year P((int));
/*
* Transfer vector
*/
struct refclock refclock_leitch = {
};
/*
* leitch_init - initialize internal leitch driver data
*/
static void
{
int i;
for (i = 0; i < MAXUNITS; i++)
}
/*
* leitch_shutdown - shut down a LEITCH clock
*/
static void
int unit;
{
#ifdef DEBUG
if (debug)
#endif
}
/*
* leitch_poll - called by the transmit procedure
*/
static void
int unit;
{
struct leitchunit *leitch;
/* start the state machine rolling */
#ifdef DEBUG
if (debug)
#endif
/* XXXX syslog it */
return;
}
/* reset and wait for next poll */
/* XXXX syslog it */
} else {
}
}
static void
int unit;
struct refclockstat *in;
struct refclockstat *out;
{
"leitch_control: unit %d invalid", unit);
return;
}
if (in) {
}
}
if (out) {
}
}
/*
* leitch_start - open the LEITCH devices and initialize data for processing
*/
static int
int unit;
{
struct leitchunit *leitch;
int fd232;
char leitchdev[20];
/*
* Check configuration info.
*/
return (0);
}
return (0);
}
/*
* Open serial port.
*/
if (fd232 == -1) {
"leitch_start: open of %s: %m", leitchdev);
return (0);
}
#if defined(HAVE_SYSV_TTYS)
/*
* System V serial line parameters (termio interface)
*
*/
"leitch_start: ioctl(%s, TCGETA): %m", leitchdev);
goto screwed;
}
"leitch_start: ioctl(%s, TCSETA): %m", leitchdev);
goto screwed;
}
}
#endif /* HAVE_SYSV_TTYS */
#if defined(HAVE_TERMIOS)
/*
* POSIX serial line parameters (termios interface)
*
* The LEITCHCLK option provides timestamping at the driver level.
* It requires the tty_clk streams module.
*
* The LEITCHPPS option provides timestamping at the driver level.
* It uses a 1-pps signal and level converter (gadget box) and
* requires the ppsclock streams module and SunOS 4.1.1 or
* later.
*/
"leitch_start: tcgetattr(%s): %m", leitchdev);
goto screwed;
}
"leitch_start: tcsetattr(%s): %m", leitchdev);
goto screwed;
}
"leitch_start: tcflush(%s): %m", leitchdev);
goto screwed;
}
}
#endif /* HAVE_TERMIOS */
#ifdef STREAM
#if defined(LEITCHCLK)
"leitch_start: ioctl(%s, I_PUSH, clk): %m", leitchdev);
"leitch_start: ioctl(%s, CLK_SETSTR): %m", leitchdev);
#endif /* LEITCHCLK */
#if defined(LEITCHPPS)
"leitch_start: ioctl(%s, I_PUSH, ppsclock): %m", leitchdev);
else
#endif /* LEITCHPPS */
#endif /* STREAM */
#if defined(HAVE_BSD_TTYS)
/*
* 4.3bsd serial line parameters (sgttyb interface)
*
* The LEITCHCLK option provides timestamping at the driver level.
* It requires the tty_clk line discipline and 4.3bsd or later.
*/
#if defined(LEITCHCLK)
#endif /* LEITCHCLK */
"leitch_start: ioctl(%s, TIOCGETP): %m", leitchdev);
goto screwed;
}
#if defined(LEITCHCLK)
#else
#endif /* LEITCHCLK */
"leitch_start: ioctl(%s, TIOCSETP): %m", leitchdev);
goto screwed;
}
#if defined(LEITCHCLK)
"leitch_start: ioctl(%s, TIOCSETD): %m",leitchdev);
goto screwed;
}
#endif /* LEITCHCLK */
}
#endif /* HAVE_BSD_TTYS */
/*
* Set up the structures
*/
goto screwed;
}
/*
* All done. Initialize a few random peer variables, then
* return success. Note that root delay and root dispersion are
* always zero for this clock.
*/
peer->rootdispersion = 0;
return(1);
/*
* Something broke; abandon ship.
*/
return(0);
}
/*
* leitch_receive - receive data from the serial interface on a leitch
* clock
*/
static void
{
#ifdef DEBUG
if (debug)
rbufp->recv_buffer);
#endif
return; /* The date is return with a trailing newline,
discard it. */
case STATE_IDLE: /* unexpected, discard and resync */
return;
case STATE_DATE:
break;
}
#ifdef DEBUG
if (debug)
#endif
break;
case STATE_TIME1:
}
break;
}
#ifdef DEBUG
if (debug)
#endif
break;
case STATE_TIME2:
}
break;
}
#ifdef DEBUG
if (debug)
#endif
break;
case STATE_TIME3:
}
break;
}
#ifdef DEBUG
if (debug)
#endif
break;
default:
"leitech_receive: invalid state %d unit %d",
}
}
/*
* leitch_process - process a pile of samples from the clock
*
* This routine uses a three-stage median filter to calculate offset and
* dispersion. reduce jitter. The dispersion is calculated as the span
* of the filter (max - min), unless the quality character (format 2) is
* non-blank, in which case the dispersion is calculated on the basis of
* the inherent tolerance of the internal radio oscillator, which is
* +-2e-5 according to the radio specifications.
*/
static void
struct leitchunit *leitch;
{
int isinsync = 1;
delay = 20;
#ifdef DEBUG
if (debug)
#endif
#ifdef DEBUG
if (debug)
#endif
#ifdef DEBUG
if (debug)
#endif
}
#if 0 /* Unused... */
/*
* leitch_timeout
*/
static void
{
#ifdef DEBUG
if (debug)
#endif
#ifdef NOTYET
case STATE_IDLE:
break;
case STATE_DATE:
break;
case STATE_TIME1:
case STATE_TIME2:
case STATE_TIME3:
default:
break;
}
}
#endif /* NOTYET */
}
#endif /* 0 */
/*
* days_per_year
*/
static int
int year;
{
return (365);
} else {
return (366);
} else {
if (year % 400) {
return (365);
} else {
return (366);
}
}
}
}
static int
struct leitchunit *leitch;
{
int i;
return(0);
#ifdef BAD
#endif
return(0);
/* sanity checks */
return(0);
return(0);
/* calculate yearday */
i = 0;
return(1);
}
/*
* leitch_get_time
*/
static int
struct leitchunit *leitch;
int which;
{
return(0);
return(0);
return(1);
}
#else /* not (REFCLOCK && LEITCH) */
int refclock_leitch_bs;
#endif /* not (REFCLOCK && LEITCH) */