+1999-10-15 Harlan Stenn <stenn@whimsy.udel.edu>
+
+ * ntpd/refclock_wwvb.c:
+ * ntpd/refclock_usno.c:
+ * ntpd/refclock_ulink.c:
+ * ntpd/refclock_tpro.c:
+ * ntpd/refclock_pst.c:
+ * ntpd/refclock_parse.c:
+ * ntpd/refclock_palisade.c:
+ * ntpd/refclock_oncore.c:
+ * ntpd/refclock_mx4200.c:
+ * ntpd/refclock_msfees.c:
+ * ntpd/refclock_jupiter.c:
+ * ntpd/refclock_irig.c:
+ * ntpd/refclock_heath.c:
+ * ntpd/refclock_chu.c:
+ * ntpd/refclock_atom.c:
+ * ntpd/refclock_as2201.c:
+ * ntpd/refclock_arc.c:
+ * ntpd/refclock_arbiter.c:
+ * ntpd/refclock_acts.c:
+ * ntpd/ntp_refclock.c:
+ * include/ntp_refclock.h:
+ Bunches of fixes.
+ From: Dave Mills <mills@udel.edu>
+
1999-10-10 Harlan Stenn <stenn@whimsy.udel.edu>
* html/driver16.htm: New version
int second; /* second of minute */
int msec; /* millisecond of second */
long usec; /* microsecond of second (alt) */
- int nstages; /* median filter stages */
- int nskeep; /* trimmed filter stages */
u_long yearstart; /* beginning of year */
- u_long coderecv; /* sample counter */
+ int coderecv; /* put pointer */
+ int codeproc; /* get pointer */
l_fp lastref; /* timecode timestamp */
l_fp lastrec; /* local timestamp */
double offset; /* mean offset */
/*
* auxiliary PPS interface (implemented by refclock_atom())
*/
-#ifdef PPS_SAMPLE
-extern int pps_sample P((l_fp *));
-#endif
-
+extern int pps_sample P((l_fp *));
extern int io_addclock_simple P((struct refclockio *));
extern int io_addclock P((struct refclockio *));
extern void io_closeclock P((struct refclockio *));
extern void refclock_transmit P((struct peer *));
extern int refclock_ioctl P((int, int));
extern int refclock_process P((struct refclockproc *));
-extern int refclock_process_offset P((struct refclockproc *, l_fp, l_fp, double));
-extern void refclock_sample P((struct refclockproc *));
+extern void refclock_process_offset P((struct refclockproc *, l_fp, l_fp, double));
extern void refclock_report P((struct peer *, int));
extern int refclock_gtlin P((struct recvbuf *, char *, int,
l_fp *));
static int refclock_cmpl_fp P((const double *, const double *));
#endif
+static int refclock_sample(struct refclockproc *);
+
#ifdef HAVE_PPSAPI
extern int pps_assert;
extern int pps_hardpps;
pp->type = clktype;
pp->timestarted = current_time;
- pp->nstages = NSTAGE;
- pp->nskeep = NSTAGE * 3 / 5;
/*
* If the interface has been set to any_interface, set it to the
} else if (peer->valid > NTP_SHIFT - 2)
hpoll++;
if (peer->flags & FLAG_BURST)
- peer->burst = pp->nstages;
+ peer->burst = NSTAGE;
}
peer->outdate = current_time;
}
/*
* refclock_process_offset - process a pile of offset samples from the clock
*
- * This routine uses the given offset and receive time stamp
- * and fill the appropriate filter buffers further processing is left to
- * refclock_sample
+ * This routine uses the given offset and receive time stamp and fill the
+ * appropriate filter buffers further processing is left to refclock_sample.
+ * Samples that overflow the buffer are quietly discarded.
*/
-int
+void
refclock_process_offset(
struct refclockproc *pp,
l_fp offset,
)
{
double doffset;
-
+
+ if ((pp->coderecv + 1) % MAXSTAGE == pp->codeproc % MAXSTAGE)
+ return;
pp->lastref = offset;
pp->lastrec = lastrec;
pp->variance = 0;
L_SUB(&offset, &lastrec);
LFPTOD(&offset, doffset);
- pp->filter[pp->coderecv++ % pp->nstages] = doffset + fudge;
- return (1);
+ pp->filter[pp->coderecv++ % MAXSTAGE] = doffset + fudge;
}
/*
} else {
MSUTOTSF(pp->msec, offset.l_uf);
}
- return refclock_process_offset(pp, offset, pp->lastrec, pp->fudgetime1);
+ refclock_process_offset(pp, offset, pp->lastrec, pp->fudgetime1);
+ return (1);
}
/*
* failure due to invalid timecode data or very noisy offsets.
*
*/
-void
+static int
refclock_sample(
struct refclockproc *pp
)
{
- int i, j, k;
+ int i, j, k, n;
double offset, disp;
double off[MAXSTAGE];
/*
- * Copy the raw offsets and sort into ascending order.
+ * Copy the raw offsets and sort into ascending order. Don't do
+ * anything if the buffer is empty.:1
*/
- for (j = 0; j < pp->nstages && (u_int)j < pp->coderecv; j++)
- off[j] = pp->filter[j];
- qsort((char *)off, (u_int)j, sizeof(double), refclock_cmpl_fp);
+ if (pp->codeproc == pp->coderecv)
+ return (0);
+ n = 0;
+ while (pp->codeproc != pp->coderecv)
+ off[n++] = pp->filter[pp->codeproc++ % MAXSTAGE];
+ if (n > 1)
+ qsort((char *)off, n, sizeof(double), refclock_cmpl_fp);
/*
* Reject the furthest from the median of the samples until
- * nskeep samples remain.
+ * approximately 60 percent of the samples remain.
*/
- i = 0;
- k = j;
- if (k > pp->nskeep)
- k = pp->nskeep;
+ i = 0; j = n;
+ k = n - (n * 2) / NSTAGE;
while ((j - i) > k) {
offset = off[(j + i) / 2];
if (off[j - 1] - offset < offset - off[i])
#ifdef DEBUG
if (debug)
printf(
- "refclock_sample: offset %.6f disp %.6f std %.6f\n",
- pp->offset, pp->disp, SQRT(pp->variance));
+ "refclock_sample: n %d offset %.6f disp %.6f std %.6f\n",
+ n, pp->offset, pp->disp, SQRT(pp->variance));
#endif
+ return (1);
}
peer->reftime = peer->org = pp->lastrec;
peer->rootdispersion = pp->disp + SQRT(pp->variance);
get_systime(&peer->rec);
- refclock_sample(pp);
+ if (!refclock_sample(pp))
+ return;
clock_filter(peer, pp->offset, 0., 0.);
clock_select();
record_peer_stats(&peer->srcadr, ctlpeerstatus(peer),
bug->values[5] = pp->msec;
bug->values[6] = pp->yearstart;
bug->values[7] = pp->coderecv;
-
- bug->ntimes = pp->nstages + 3;
- if (bug->ntimes > NCLKBUGTIMES)
- bug->ntimes = NCLKBUGTIMES;
bug->stimes = 0xfffffffc;
bug->times[0] = pp->lastref;
bug->times[1] = pp->lastrec;
pp->offset += (msADV - up->msADV) * 1000 * 1e-6;
} else {
up->msADV = msADV;
- pp->nstages = up->msgcnt;
- pp->nskeep = up->msgcnt * 2 / 3;
if (!refclock_process(pp)) {
refclock_report(peer, CEVNT_BADTIME);
return;
#define REFID "GPS " /* reference ID */
#define DESCRIPTION "Arbiter 1088A/B GPS Receiver" /* WRU */
-#define ARB_NSTAGE 45 /* median filter stages */
#define LENARB 24 /* format B5 timecode length */
#define MAXSTA 30 /* max length of status string */
#define MAXPOS 70 /* max length of position string */
* ARB unit control structure
*/
struct arbunit {
- int pollcnt; /* poll message counter */
l_fp laststamp; /* last receive timestamp */
int tcswitch; /* timecode switch/counter */
char qualchar; /* IEEE P1344 quality (TQ command) */
peer->precision = PRECISION;
pp->clockdesc = DESCRIPTION;
memcpy((char *)&pp->refid, REFID, 4);
- up->pollcnt = 2;
- pp->nstages = ARB_NSTAGE;
- pp->nskeep = ARB_NSTAGE * 3 / 5;
write(pp->io.fd, "B0", 2);
return (1);
}
return;
}
pp->lencode = temp;
- up->pollcnt = 2;
- up->tcswitch++;
/*
* We get down to business, check the timecode format and decode
write(pp->io.fd, "B0", 2);
return;
}
-
- /*
- * Process the new sample in the median filter and determine the
- * timecode timestamp.
- */
- if (!refclock_process(pp)) {
- refclock_report(peer, CEVNT_BADTIME);
- write(pp->io.fd, "B0", 2);
- return;
- }
- if (up->tcswitch <= pp->nstages)
- return;
- up->tcswitch = 0;
- record_clock_stats(&peer->srcadr, pp->a_lastcode);
+ up->tcswitch++;
/*
* We decode the clock dispersion from the time quality
printf("arbiter: timecode %d %s\n", pp->lencode,
pp->a_lastcode);
#endif
- write(pp->io.fd, "B0", 2);
- refclock_receive(peer);
+ if (up->tcswitch >= NSTAGE)
+ write(pp->io.fd, "B0", 2);
+
+ /*
+ * Process the new sample in the median filter and determine the
+ * timecode timestamp.
+ */
+ if (!refclock_process(pp))
+ refclock_report(peer, CEVNT_BADTIME);
}
*/
pp = peer->procptr;
up = (struct arbunit *)pp->unitptr;
- if (up->pollcnt == 0)
- refclock_report(peer, CEVNT_TIMEOUT);
- else
- up->pollcnt--;
+ up->tcswitch = 0;
if (write(pp->io.fd, "TQ", 2) != 2) {
refclock_report(peer, CEVNT_FAULT);
} else
pp->polls++;
- up->tcswitch = 0;
-
+ if (pp->coderecv == pp->codeproc) {
+ refclock_report(peer, CEVNT_TIMEOUT);
+ return;
+ }
+ record_clock_stats(&peer->srcadr, pp->a_lastcode);
+ refclock_receive(peer);
}
#else
}
#endif
- refclock_process(pp);
+ if (!refclock_process(pp)) {
+ refclock_report(peer, CEVNT_BADTIME);
+ return;
+ }
refclock_receive(peer);
}
* AS2201 unit control structure.
*/
struct as2201unit {
- int pollcnt; /* poll message counter */
-
char *lastptr; /* statistics buffer pointer */
char stats[SMAX]; /* statistics buffer */
int linect; /* count of lines remaining */
* Initialize miscellaneous variables
*/
peer->precision = PRECISION;
- peer->burst = NTP_SHIFT;
+ peer->burst = NSTAGE;
pp->clockdesc = DESCRIPTION;
memcpy((char *)&pp->refid, REFID, 4);
- up->pollcnt = 2;
-
up->lastptr = up->stats;
up->index = 0;
return (1);
up->linect = atoi(pp->a_lastcode);
return;
} else {
- up->pollcnt = 2;
record_clock_stats(&peer->srcadr, up->stats);
#ifdef DEBUG
if (debug)
return;
}
+ /*
+ * Test for synchronization (this is a temporary crock).
+ */
+ if (pp->a_lastcode[2] != ':')
+ pp->leap = LEAP_NOTINSYNC;
+ else
+ pp->leap = LEAP_NOWARNING;
+
/*
* Process the new sample in the median filter and determine the
* timecode timestamp.
return;
}
- /*
- * Test for synchronization (this is a temporary crock).
- */
- if (pp->a_lastcode[2] != ':')
- pp->leap = LEAP_NOTINSYNC;
- else
- pp->leap = LEAP_NOWARNING;
- refclock_receive(peer);
-
/*
* If CLK_FLAG4 is set, initialize the statistics buffer and
* send the next command. If not, simply write the timecode to
*/
pp = peer->procptr;
up = (struct as2201unit *)pp->unitptr;
- if (up->pollcnt == 0)
- refclock_report(peer, CEVNT_TIMEOUT);
- else
- up->pollcnt--;
if (write(pp->io.fd, "\r*toc\r", 6) != 6) {
refclock_report(peer, CEVNT_FAULT);
} else {
if (!(pp->sloppyclockflag & CLK_FLAG2))
get_systime(&pp->lastrec);
}
+ if (peer->burst > 0)
+ return;
+ peer->burst = NSTAGE;
+ if (pp->coderecv == pp->codeproc) {
+ refclock_report(peer, CEVNT_TIMEOUT);
+ return;
+ }
+ refclock_receive(peer);
}
#else
* Interface definitions
*/
#ifdef HAVE_PPSAPI /* avoid others if api available */
-#undef PPS
-#undef TTYCLK
-
extern int pps_assert;
#endif /* HAVE_PPSAPI */
-
-#ifdef PPS /* avoid tty_clk if ppsclock available */
-#undef TTYCLK
-#endif /* PPS */
-
#ifdef TTYCLK
-# define DEVICE "/dev/pps%d" /* device name and unit */
-# ifdef B38400
-# define SPEED232 B38400 /* uart speed (38400 baud) */
-# else
-# define SPEED232 EXTB /* as above */
-# endif
+#define DEVICE "/dev/pps%d" /* device name and unit */
+#ifdef B38400
+#define SPEED232 B38400 /* uart speed (38400 baud) */
+#else
+#define SPEED232 EXTB /* as above */
+#endif
#endif /* TTYCLK */
#define PRECISION (-20) /* precision assumed (about 1 us) */
#define FLAG_PPS 0x02 /* ppsclock heard from */
#define FLAG_AUX 0x04 /* auxiliary PPS source */
-#ifdef PPS_SAMPLE
static struct peer *pps_peer; /* atom driver for auxiliary PPS sources */
-#endif
#ifdef TTYCLK
static void atom_receive P((struct recvbuf *));
struct ppsclockev ev; /* ppsclock control */
#endif /* PPS */
int flags; /* flags that wave */
- int pollcnt; /* poll message counter */
};
/*
char device[20];
#endif /* TTYCLK */
+ pps_peer = peer;
flags = 0;
+
#ifdef TTYCLK
/*
* Open serial port. Use LDISC_CLKPPS line discipline only
* if the LDISC_PPS line discipline is not availble,
*/
- (void)sprintf(device, DEVICE, unit);
- if ((fd = refclock_open(device, SPEED232, LDISC_CLKPPS)) == 0)
- return (0);
- flags |= FLAG_TTY;
+ if (fdpps <= 0) {
+ (void)sprintf(device, DEVICE, unit);
+ if ((fd = refclock_open(device, SPEED232, LDISC_CLKPPS)) != 0)
+ flags |= FLAG_TTY;
+ }
#endif /* TTYCLK */
/*
}
}
#endif /* TTYCLK */
-#ifdef PPS_SAMPLE
- if (pps_peer == 0)
- pps_peer = peer;
-#endif /* PPS_SAMPLE */
+
/*
* Initialize miscellaneous variables
*/
peer->precision = PRECISION;
pp->clockdesc = DESCRIPTION;
memcpy((char *)&pp->refid, REFID, 4);
- up->pollcnt = 2;
up->flags = flags;
- pp->nstages = MAXSTAGE;
- pp->nskeep = MAXSTAGE * 3 / 5;
return (1);
}
if (up->flags & FLAG_TTY)
io_closeclock(&pp->io);
#endif /* TTYCLK */
-#ifdef PPS_SAMPLE
if (pps_peer == peer)
pps_peer = 0;
-#endif /* PPS_SAMPLE */
free(up);
}
struct timespec ts;
#else
struct timeval ts;
-#endif
+#endif /* HAVE_TIMESPEC */
l_fp lftmp;
double doffset;
int i;
L_CLR(&lftmp);
L_ADDF(&lftmp, pp->lastrec.l_f);
LFPTOD(&lftmp, doffset);
- pp->filter[pp->coderecv++ % pp->nstages] = -doffset +
+ pp->filter[pp->coderecv++ % MAXSTAGE] = -doffset +
pp->fudgetime1;
- up->pollcnt = 2 * 60;
return (0);
}
#endif /* PPS || HAVE_PPSAPI */
L_CLR(&lftmp);
L_ADDF(&lftmp, pp->lastrec.l_f);
LFPTOD(&lftmp, doffset);
- pp->filter[pp->coderecv++ % pp->nstages] = -doffset + pp->fudgetime1;
- up->pollcnt = 2;
+ pp->filter[pp->coderecv++ % MAXSTAGE] = -doffset + pp->fudgetime1;
}
#endif /* TTYCLK */
-#ifdef PPS_SAMPLE
/*
* pps_sample - receive PPS data from some other clock driver
*/
L_CLR(&lftmp);
L_ADDF(&lftmp, pp->lastrec.l_f);
LFPTOD(&lftmp, doffset);
- pp->filter[pp->coderecv++ % pp->nstages] = -doffset +
+ pp->filter[pp->coderecv++ % MAXSTAGE] = -doffset +
pp->fudgetime1;
- up->pollcnt = 2 * 60;
return (0);
}
-#endif /* PPS_SAMPLE */
/*
* atom_poll - called by the transmit procedure
if (atom_pps(peer))
return;
}
+#endif /* PPS || HAVE_PPSAPI */
if (peer->burst > 0)
return;
-#endif /* PPS || HAVE_PPSAPI */
- pp->polls++;
- if (up->pollcnt == 0) {
- refclock_report(peer, CEVNT_FAULT);
+ if (pp->coderecv == pp->codeproc) {
+ refclock_report(peer, CEVNT_TIMEOUT);
return;
}
- up->pollcnt--;
+ peer->burst = NSTAGE;
+ pp->polls++;
/*
* Valid time (leap bits zero) is returned only if the prefer
return;
}
pp->variance = 0;
+ record_clock_stats(&peer->srcadr, pp->a_lastcode);
refclock_receive(peer);
-#if defined(PPS) || defined(HAVE_PPSAPI)
- peer->burst = pp->nstages;
-#endif /* PPS || HAVE_PPSAPI */
}
#else
*/
peer->precision = PRECISION;
pp->clockdesc = DESCRIPTION;
- pp->nstages = MAXSTAGE;
- pp->nskeep = MAXSTAGE * 3 / 5;
memcpy((char *)&pp->refid, REFID, 4);
DTOLFP(CHAR, &up->charstamp);
up->pollcnt = 2;
toffset = offset;
L_SUB(&toffset, &up->tstamp[i]);
LFPTOD(&toffset, dtemp);
- pp->filter[(pp->coderecv++) % pp->nstages] = dtemp +
- FUDGE + pp->fudgetime1;
+ pp->filter[pp->coderecv++ % MAXSTAGE] = dtemp + FUDGE +
+ pp->fudgetime1;
}
if (i > 0)
refclock_receive(peer);
* Initialize miscellaneous variables
*/
peer->precision = PRECISION;
+ peer->burst = NSTAGE;
pp->clockdesc = DESCRIPTION;
memcpy((char *)&pp->refid, REFID, 4);
up->pollcnt = 2;
*/
pp->lastrec = up->tstamp;
up->pollcnt = 2;
- record_clock_stats(&peer->srcadr, pp->a_lastcode);
#ifdef DEBUG
if (debug)
printf("heath: timecode %d %s\n", pp->lencode,
pp->msec = (dsec - '0') * 100;
pp->leap = LEAP_NOWARNING;
}
- if (!refclock_process(pp)) {
+ if (!refclock_process(pp))
refclock_report(peer, CEVNT_BADTIME);
- return;
- }
- refclock_receive(peer);
}
*/
pp = peer->procptr;
up = (struct heathunit *)pp->unitptr;
- if (up->pollcnt == 0)
- refclock_report(peer, CEVNT_TIMEOUT);
- else
- up->pollcnt--;
pp->polls++;
/*
* pulse might get too short. Later.
*/
if (ioctl(pp->io.fd, TIOCMBIC, (char *)&bits) < 0)
- refclock_report(peer, CEVNT_FAULT);
+ refclock_report(peer, CEVNT_FAULT);
get_systime(&up->tstamp);
ioctl(pp->io.fd, TIOCMBIS, (char *)&bits);
-
+ if (peer->burst > 0)
+ return;
+ peer->burst = NSTAGE;
+ if (pp->coderecv == pp->codeproc) {
+ refclock_report(peer, CEVNT_TIMEOUT);
+ return;
+ }
+ record_clock_stats(&peer->srcadr, pp->a_lastcode);
+ refclock_receive(peer);
}
#else
up->tc = MINTC;
up->decim = 1;
up->fdelay = IRIG_B;
- pp->nstages = 50;
- pp->nskeep = 30;
up->gain = (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN) / 2;
if (irig_audio() < 0) {
io_closeclock(&pp->io);
if (up->irig_b > up->irig_e) {
up->decim = 1;
up->fdelay = IRIG_B;
- pp->nstages = 50;
- pp->nskeep = 30;
} else {
up->decim = 10;
up->fdelay = IRIG_E;
- pp->nstages = 5;
- pp->nskeep = 3;
}
if (pp->sloppyclockflag & CLK_FLAG2)
up->port = AUDIO_LINE_IN;
up->timecnt++;
refclock_process(pp);
}
- if (up->timecnt >= pp->nstages) {
+ if (up->timecnt >= MAXSTAGE) {
refclock_receive(peer);
up->timecnt = 0;
up->pollcnt = 2;
*/
pp->lastref = up->lastref;
pp->coderecv = up->coderecv;
- pp->nstages = up->nkeep + 2;
pp->filter[0] = off[0]; /* smallest offset */
pp->filter[1] = off[NSAMPLES-1]; /* largest offset */
for (j = 2, k = i; k < n; j++, k++)
unitinuse[unit] = 1;
pp->unitptr = (caddr_t) &eesunits[unit];
pp->clockdesc = EESDESCRIPTION;
- pp->nstages = MAXSTAGE;
msyslog(LOG_ERR, "ees clock: %s OK on %d", eesdev, unit);
return (1);
up->last_leap = 0; /* LEAP_NOWARNING */
up->clamp_time = current_time + (AVGING_TIME * 60 * 60);
up->log_time = current_time + SLEEPTIME;
- pp->nstages = MNSAMPLES;
- pp->nskeep = MNKEEP;
/*
* "007" Control Port Configuration
}
memset((char *) instance, 0, sizeof *instance);
pp = peer->procptr;
- pp->nstages = 16;
- pp->nskeep = pp->nstages * 3 / 5;
-
pp->unitptr = (caddr_t)instance;
instance->unit = unit;
instance->ttyfd = fd1;
pp->io.srcclock = (caddr_t)peer;
pp->io.datalen = 0;
pp->io.fd = fd;
- pp->nstages = 1;
-#ifndef PALISADE
- pp->nskeep = 1;
-#endif
-
if (!io_addclock(&pp->io)) {
#ifdef DEBUG
printf("Palisade(%d) io_addclock\n",unit);
}
#endif
- if (!refclock_process_offset(parse->generic, reftime, rectime, fudge))
- {
- parse_event(parse, CEVNT_BADTIME);
- return;
- }
-
+ 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);
* Initialize miscellaneous variables
*/
peer->precision = PRECISION;
- peer->flags |= FLAG_BURST;
- peer->burst = pp->nstages;
+ peer->burst = NSTAGE;
pp->clockdesc = DESCRIPTION;
memcpy((char *)&pp->refid, WWVREFID, 4);
return (1);
return;
}
- /*
- * Process the new sample in the median filter and determine the
- * timecode timestamp.
- */
- if (!refclock_process(pp)) {
- refclock_report(peer, CEVNT_BADTIME);
- peer->burst = 0;
- return;
- }
- if (peer->burst > 0)
- return;
- record_clock_stats(&peer->srcadr, pp->a_lastcode);
-
/*
* Decode synchronization, quality and last update. If
* unsynchronized, set the leap bits accordingly and exit. Once
if (peer->stratum <= 1)
peer->refid = pp->refid;
pp->disp = PST_PHI * ltemp;
- refclock_receive(peer);
+
+ /*
+ * Process the new sample in the median filter and determine the
+ * timecode timestamp.
+ */
+ if (!refclock_process(pp))
+ refclock_report(peer, CEVNT_BADTIME);
+
}
*/
pp = peer->procptr;
up = (struct pstunit *)pp->unitptr;
- if (peer->burst ==0 && peer->reach == 0)
- refclock_report(peer, CEVNT_TIMEOUT);
up->tcswitch = 0;
up->lastptr = pp->a_lastcode;
if (write(pp->io.fd, "QTQDQMT", 6) != 6)
refclock_report(peer, CEVNT_FAULT);
else
pp->polls++;
+ if (peer->burst > 0)
+ return;
+ peer->burst = NSTAGE;
+ if (pp->coderecv == pp->codeproc) {
+ refclock_report(peer, CEVNT_TIMEOUT);
+ return;
+ }
+ record_clock_stats(&peer->srcadr, pp->a_lastcode);
+ refclock_receive(peer);
}
#else
* Initialize miscellaneous peer variables
*/
peer->precision = PRECISION;
- peer->flags |= FLAG_BURST;
- peer->burst = pp->nstages;
+ peer->burst = pp->NSTAGE;
pp->clockdesc = DESCRIPTION;
memcpy((char *)&pp->refid, REFID, 4);
return (1);
refclock_report(peer, CEVNT_BADTIME);
return;
}
+ if (!tp->status & 0x3)
+ pp->leap = LEAP_NOTINSYNC;
+ else
+ pp->leap = LEAP_NOWARNING;
if (!refclock_process(pp)) {
refclock_report(peer, CEVNT_BADTIME);
peer->burst = 0;
}
if (peer->burst > 0)
return;
+ peer->burst = NSTAGE;
+ if (pp->coderecv == pp->codeproc) {
+ refclock_report(peer, CEVNT_TIMEOUT);
+ return;
+ }
record_clock_stats(&peer->srcadr, pp->a_lastcode);
- if (!tp->status & 0x3)
- pp->leap = LEAP_NOTINSYNC;
- else
- pp->leap = LEAP_NOWARNING;
refclock_receive(peer);
}
*/
peer->precision = PRECISION;
peer->flags |= FLAG_BURST;
- peer->burst = pp->nstages;
+ peer->burst = NSTAGE;
pp->clockdesc = DESCRIPTION;
memcpy((char *)&pp->refid, REFID, 4);
return (1);
&syncchar, &qualchar, &modechar, &pp->year, &pp->day,
&leapchar,&pp->hour, &pp->minute, &pp->second,&pp->msec);
- pp->msec*=10; /* M320 returns 10's of msecs */
-
- /*
- * Process the new sample in the median filter and determine the
- * timecode timestamp.
- */
- if (!refclock_process(pp)) {
- refclock_report(peer, CEVNT_BADTIME);
- peer->burst = 0;
- return;
- }
- if (peer->burst > 0)
- return;
-
- record_clock_stats(&peer->srcadr, pp->a_lastcode);
-
- qualchar=' ';
+ pp->msec *= 10; /* M320 returns 10's of msecs */
+ qualchar = ' ';
/*
* Decode synchronization, quality and leap characters. If
* quality character.
*/
pp->disp = .001;
-
pp->leap = LEAP_NOWARNING;
- refclock_receive(peer);
/*
- * If the monitor flag is set (flag4), we dump the internal
- * quality table at the first timecode beginning the day.
+ * Process the new sample in the median filter and determine the
+ * timecode timestamp.
*/
- if (pp->sloppyclockflag & CLK_FLAG4 && pp->hour <
- (int)up->lasthour)
- up->linect = MONLIN;
- up->lasthour = pp->hour;
+ if (!refclock_process(pp))
+ refclock_report(peer, CEVNT_BADTIME);
}
struct peer *peer
)
{
+ register struct ulinkunit *up;
struct refclockproc *pp;
char pollchar;
pp = peer->procptr;
+ up = (struct wwvbunit *)pp->unitptr;
pollchar = 'T';
- write(pp->io.fd, &pollchar, 1);
- pp->polls++;
+ if (write(pp->io.fd, &pollchar, 1) != 1)
+ refclock_report(peer, CEVNT_FAULT);
+ else
+ pp->polls++;
+ if (peer->burst > 0)
+ return;
+ peer->burst = NSTAGE;
+ if (pp->coderecv == pp->codeproc) {
+ refclock_report(peer, CEVNT_TIMEOUT);
+ return;
+ }
+ record_clock_stats(&peer->srcadr, pp->a_lastcode);
+ refclock_receive(peer);
+
+ /*
+ * If the monitor flag is set (flag4), we dump the internal
+ * quality table at the first timecode beginning the day.
+ */
+ if (pp->sloppyclockflag & CLK_FLAG4 && pp->hour <
+ (int)up->lasthour)
+ up->linect = MONLIN;
+ up->lasthour = pp->hour;
}
#else
* dispersion. The fudge time1 value is added to each sample as
* received.
*/
- pp->nstages = up->msgcnt;
- pp->nskeep = up->msgcnt * 2 / 3;
if (!refclock_process(pp)) {
#ifdef DEBUG
if (debug)
/*
* This driver supports the Spectracom Model 8170 and Netclock/2 WWVB
- * Synchronized Clock. This clock has proven a reliable source of time,
- * except in some cases of high ambient conductive RF interference. The
- * claimed accuracy of the clock is 100 usec relative to the broadcast
- * signal; however, in most cases the actual accuracy is limited by the
- * precision of the timecode and the latencies of the serial interface
- * and operating system.
+ * Synchronized Clocks and the Netclock/GPS Master Clock. Both the WWVB
+ * and GPS clocks have proven reliable sources of time; however, the
+ * WWVB clocks have proven vulnerable to high ambient conductive RF
+ * interference. The claimed accuracy of the WWVB clocks is 100 us
+ * relative to the broadcast signal, while the claimed accuracy of the
+ * GPS clock is 50 ns; however, in most cases the actual accuracy is
+ * limited by the resolution of the timecode and the latencies of the
+ * serial interface and operating system.
*
- * The DIPswitches on this clock should be set to 24-hour display, AUTO
- * DST off, time zone 0 (UTC), data format 0 or 2 (see below) and baud
- * rate 9600. If this clock is to used as the source for the IRIG Audio
- * Decoder (refclock_irig.c in this distribution), set the DIPswitches
- * for AM IRIG output and IRIG format 1 (IRIG B with signature control).
+ * The WWVB and GPS clocks should be configured for 24-hour display,
+ * AUTO DST off, time zone 0 (UTC), data format 0 or 2 (see below) and
+ * baud rate 9600. If the clock is to used as the source for the IRIG
+ * Audio Decoder (refclock_irig.c in this distribution), it should be
+ * configured for AM IRIG output and IRIG format 1 (IRIG B with
+ * signature control). The GPS clock can be configured either to respond
+ * to a 'T' poll character or left running continuously.
*
* There are two timecode formats used by these clocks. Format 0, which
* is available with both the Netclock/2 and 8170, and format 2, which
- * is available only with the Netclock/2 and specially modified 8170.
+ * is available only with the Netclock/2, specially modified 8170 and
+ * GPS.
*
* Format 0 (22 ASCII printing characters):
*
* hh:mm:ss = hours, minutes, seconds
* i = synchronization flag (' ' = in synch, '?' = out of synch)
*
- * The alarm condition is indicated by other than ' ' at A, which occurs
+ * The alarm condition is indicated by other than ' ' at a, which occurs
* during initial synchronization and when received signal is lost for
* about ten hours.
*
* ddd = day of year
* hh:mm:ss.fff = hours, minutes, seconds, milliseconds
*
- * The alarm condition is indicated by other than ' ' at A, which occurs
+ * The alarm condition is indicated by other than ' ' at a, which occurs
* during initial synchronization and when received signal is lost for
* about ten hours. The unlock condition is indicated by other than ' '
- * at Q.
+ * at q.
*
- * The Q is normally ' ' when the time error is less than 1 ms and a
+ * The q is normally ' ' when the time error is less than 1 ms and a
* character in the set 'A'...'D' when the time error is less than 10,
- * 100, 500 and greater than 500 ms respectively. The L is normally ' ',
+ * 100, 500 and greater than 500 ms respectively. The l is normally ' ',
* but is set to 'L' early in the month of an upcoming UTC leap second
- * and reset to ' ' on the first day of the following month. The D is
+ * and reset to ' ' on the first day of the following month. The d is
* set to 'S' for standard time 'I' on the day preceding a switch to
* daylight time, 'D' for daylight time and 'O' on the day preceding a
* switch to standard time. The start bit of the first <cr> is
* synchronized to the indicated time as returned.
*
* This driver does not need to be told which format is in use - it
- * figures out which one from the length of the message. A three-stage
- * median filter is used to reduce jitter and provide a dispersion
- * measure. The driver makes no attempt to correct for the intrinsic
- * jitter of the radio itself, which is a known problem with the older
- * radios.
+ * figures out which one from the length of the message.The driver makes
+ * no attempt to correct for the intrinsic jitter of the radio itself,
+ * which is a known problem with the older radios.
*
* Fudge Factors
*
* This driver can retrieve a table of quality data maintained
- * internally by the Netclock/2 receiver. If flag4 of the fudge
+ * internally by the Netclock/2 clock. If flag4 of the fudge
* configuration command is set to 1, the driver will retrieve this
* table and write it to the clockstats file on when the first timecode
* message of a new day is received.
#define SPEED232 B9600 /* uart speed (9600 baud) */
#define PRECISION (-13) /* precision assumed (about 100 us) */
#define REFID "WWVB" /* reference ID */
-#define DESCRIPTION "Spectracom WWVB Receiver" /* WRU */
+#define DESCRIPTION "Spectracom WWVB/GPS Receivers" /* WRU */
#define LENWWVB0 22 /* format 0 timecode length */
#define LENWWVB2 24 /* format 2 timecode length */
* Initialize miscellaneous variables
*/
peer->precision = PRECISION;
- peer->flags |= FLAG_BURST;
- peer->burst = pp->nstages;
+ peer->burst = NSTAGE;
pp->clockdesc = DESCRIPTION;
memcpy((char *)&pp->refid, REFID, 4);
return (1);
struct peer *peer;
l_fp trtmp; /* arrival timestamp */
+ int tz; /* time zone */
+ int day, month; /* ddd conversion */
+ int temp; /* int temp */
char syncchar; /* synchronization indicator */
char qualchar; /* quality indicator */
char leapchar; /* leap indicator */
char dstchar; /* daylight/standard indicator */
- int tz; /* time zone */
- int day, month; /* ddd conversion */
- int temp; /* int temp */
/*
* Initialize pointers and read the timecode and timestamp
/*
* We get down to business, check the timecode format and decode
* its contents. This code uses the timecode length to determine
- * whether format 0 or format 2. If the timecode has invalid
- * length or is not in proper format, we declare bad format and
- * exit.
+ * format 0, 2 or 3. If the timecode has invalid length or is
+ * not in proper format, we declare bad format and exit.
*/
syncchar = qualchar = leapchar = dstchar = ' ';
tz = 0;
/*
* Timecode format 0: "I ddd hh:mm:ss DTZ=nn"
*/
- if (sscanf(pp->a_lastcode, "%c %3d %2d:%2d:%2d %cTZ=%2d",
+ if (sscanf(pp->a_lastcode,
+ "%c %3d %2d:%2d:%2d %cTZ=%2d",
&syncchar, &pp->day, &pp->hour, &pp->minute,
&pp->second, &dstchar, &tz) == 7)
break;
/*
* Timecode format 2: "IQyy ddd hh:mm:ss.mmm LD"
*/
- if (sscanf(pp->a_lastcode, "%c%c %2d %3d %2d:%2d:%2d.%3d %c",
+ if (sscanf(pp->a_lastcode,
+ "%c%c %2d %3d %2d:%2d:%2d.%3d %c",
&syncchar, &qualchar, &pp->year, &pp->day,
&pp->hour, &pp->minute, &pp->second, &pp->msec,
&leapchar) == 9)
if (sscanf(pp->a_lastcode,
"0003%c %4d%2d%2d %2d%2d%2d+0000%c%c",
&syncchar, &pp->year, &month, &day, &pp->hour,
- &pp->minute, &pp->second, &dstchar, &leapchar) == 8) {
+ &pp->minute, &pp->second, &dstchar, &leapchar) == 8)
+ {
pp->day = ymd2yd(pp->year, month, day);
break;
}
default:
- if (up->linect > 0)
+ /*
+ * Unknown format: If dumping internal table, record
+ * stats; otherwise, declare bad format.
+ */
+ if (up->linect > 0) {
up->linect--;
- else
+ record_clock_stats(&peer->srcadr,
+ pp->a_lastcode);
+ } else {
refclock_report(peer, CEVNT_BADREPLY);
+ }
return;
}
- /*
- * Process the new sample in the median filter and determine the
- * timecode timestamp.
- */
- if (!refclock_process(pp)) {
- refclock_report(peer, CEVNT_BADTIME);
- peer->burst = 0;
- return;
- }
- if (peer->burst > 0)
- return;
-
- record_clock_stats(&peer->srcadr, pp->a_lastcode);
-
/*
* Decode synchronization, quality and leap characters. If
* unsynchronized, set the leap bits accordingly and exit.
pp->leap = LEAP_ADDSECOND;
else
pp->leap = LEAP_NOWARNING;
- refclock_receive(peer);
/*
- * If the monitor flag is set (flag4), we dump the internal
- * quality table at the first timecode beginning the day.
+ * Process the new sample in the median filter and determine the
+ * timecode timestamp.
*/
- if (pp->sloppyclockflag & CLK_FLAG4 && pp->hour <
- (int)up->lasthour)
- up->linect = MONLIN;
- up->lasthour = pp->hour;
+ if (!refclock_process(pp))
+ refclock_report(peer, CEVNT_BADTIME);
}
{
register struct wwvbunit *up;
struct refclockproc *pp;
- char pollchar;
+ char pollchar; /* character sent to clock */
/*
* Time to poll the clock. The Spectracom clock responds to a
* 'T' by returning a timecode in the format(s) specified above.
* Note there is no checking on state, since this may not be the
* only customer reading the clock. Only one customer need poll
- * the clock; all others just listen in. If nothing is heard
- * from the clock for two polls, declare a timeout and keep
- * going.
+ * the clock; all others just listen in. If the clock becomes
+ * unreachable, declare a timeout and keep going.
*/
pp = peer->procptr;
up = (struct wwvbunit *)pp->unitptr;
- if (peer->burst == 0 && peer->reach == 0)
- refclock_report(peer, CEVNT_TIMEOUT);
if (up->linect > 0)
pollchar = 'R';
else
refclock_report(peer, CEVNT_FAULT);
else
pp->polls++;
+ if (peer->burst > 0)
+ return;
+ peer->burst = NSTAGE;
+ if (pp->coderecv == pp->codeproc) {
+ refclock_report(peer, CEVNT_TIMEOUT);
+ return;
+ }
+ record_clock_stats(&peer->srcadr, pp->a_lastcode);
+ refclock_receive(peer);
+
+ /*
+ * If the monitor flag is set (flag4), we dump the internal
+ * quality table at the first timecode beginning the day.
+ */
+ if (pp->sloppyclockflag & CLK_FLAG4 && pp->hour <
+ (int)up->lasthour)
+ up->linect = MONLIN;
+ up->lasthour = pp->hour;
}
#else
+++ /dev/null
-ntp_request.c: ik->offset = htonl((u_int32)ntx.offset);
-ntp_request.c: ik->freq = htonl((u_int32)ntx.freq);
-ntp_request.c: ik->maxerror = htonl((u_int32)ntx.maxerror);
-ntp_request.c: ik->esterror = htonl((u_int32)ntx.esterror);
-ntp_request.c: ik->status = htons(ntx.status);
-ntp_request.c: ik->constant = htonl((u_int32)ntx.constant);
-ntp_request.c: ik->precision = htonl((u_int32)ntx.precision);
-ntp_request.c: ik->tolerance = htonl((u_int32)ntx.tolerance);
-ntp_request.c: ik->ppsfreq = htonl((u_int32)ntx.ppsfreq);
-ntp_request.c: ik->jitter = htonl((u_int32)ntx.jitter);
-ntp_request.c: ik->shift = htons(ntx.shift);
-ntp_request.c: ik->stabil = htonl((u_int32)ntx.stabil);
-ntp_request.c: ik->jitcnt = htonl((u_int32)ntx.jitcnt);
-ntp_request.c: ik->calcnt = htonl((u_int32)ntx.calcnt);
-ntp_request.c: ik->errcnt = htonl((u_int32)ntx.errcnt);
-ntp_request.c: ik->stbcnt = htonl((u_int32)ntx.stbcnt);
-ntp_request.c~: ik->offset = htonl((u_int32)ntx.offset);
-ntp_request.c~: ik->freq = htonl((u_int32)ntx.freq);
-ntp_request.c~: ik->maxerror = htonl((u_int32)ntx.maxerror);
-ntp_request.c~: ik->esterror = htonl((u_int32)ntx.esterror);
-ntp_request.c~: ik->status = htons(ntx.status);
-ntp_request.c~: ik->constant = htonl((u_int32)ntx.constant);
-ntp_request.c~: ik->precision = htonl((u_int32)ntx.precision);
-ntp_request.c~: ik->tolerance = htonl((u_int32)ntx.tolerance);
-ntp_request.c~: ik->ppsfreq = htonl((u_int32)ntx.ppsfreq);
-ntp_request.c~: ik->jitter = htonl((u_int32)ntx.jitter);
-ntp_request.c~: ik->shift = htons(ntx.shift);
-ntp_request.c~: ik->stabil = htonl((u_int32)ntx.stabil);
-ntp_request.c~: ik->jitcnt = htonl((u_int32)ntx.jitcnt);
-ntp_request.c~: ik->calcnt = htonl((u_int32)ntx.calcnt);
-ntp_request.c~: ik->errcnt = htonl((u_int32)ntx.errcnt);
-ntp_request.c~: ik->stbcnt = htonl((u_int32)ntx.stbcnt);