xref: /freebsd/contrib/ntp/ntpd/ntp_refclock.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
1 /*
2  * ntp_refclock - processing support for reference clocks
3  */
4 #ifdef HAVE_CONFIG_H
5 # include <config.h>
6 #endif
7 
8 #include <stdio.h>
9 #include <sys/types.h>
10 #ifdef HAVE_SYS_IOCTL_H
11 # include <sys/ioctl.h>
12 #endif /* HAVE_SYS_IOCTL_H */
13 
14 #include "ntpd.h"
15 #include "ntp_io.h"
16 #include "ntp_unixtime.h"
17 #include "ntp_refclock.h"
18 #include "ntp_stdlib.h"
19 
20 #ifdef REFCLOCK
21 
22 #ifdef TTYCLK
23 # ifdef HAVE_SYS_CLKDEFS_H
24 #  include <sys/clkdefs.h>
25 # endif
26 # ifdef HAVE_SYS_SIO_H
27 #  include <sys/sio.h>
28 # endif
29 #endif /* TTYCLK */
30 
31 #ifdef HAVE_PPSCLOCK_H
32 #include <sys/ppsclock.h>
33 #endif /* HAVE_PPSCLOCK_H */
34 
35 #ifdef HAVE_PPSAPI
36 # ifdef HAVE_TIMEPPS_H
37 #  include <timepps.h>
38 # else
39 #  ifdef HAVE_SYS_TIMEPPS_H
40 #   include <sys/timepps.h>
41 #  endif
42 # endif
43 #endif /* HAVE_PPSAPI */
44 
45 /*
46  * Reference clock support is provided here by maintaining the fiction
47  * that the clock is actually a peer. As no packets are exchanged with a
48  * reference clock, however, we replace the transmit, receive and packet
49  * procedures with separate code to simulate them. Routines
50  * refclock_transmit() and refclock_receive() maintain the peer
51  * variables in a state analogous to an actual peer and pass reference
52  * clock data on through the filters. Routines refclock_peer() and
53  * refclock_unpeer() are called to initialize and terminate reference
54  * clock associations. A set of utility routines is included to open
55  * serial devices, process sample data, edit input lines to extract
56  * embedded timestamps and to peform various debugging functions.
57  *
58  * The main interface used by these routines is the refclockproc
59  * structure, which contains for most drivers the decimal equivalants of
60  * the year, day, month, hour, second and millisecond/microsecond
61  * decoded from the ASCII timecode. Additional information includes the
62  * receive timestamp, exception report, statistics tallies, etc. In
63  * addition, there may be a driver-specific unit structure used for
64  * local control of the device.
65  *
66  * The support routines are passed a pointer to the peer structure,
67  * which is used for all peer-specific processing and contains a pointer
68  * to the refclockproc structure, which in turn containes a pointer to
69  * the unit structure, if used. The peer structure is identified by an
70  * interface address in the dotted quad form 127.127.t.u, where t is the
71  * clock type and u the unit. Some legacy drivers derive the
72  * refclockproc structure pointer from the table typeunit[type][unit].
73  * This interface is strongly discouraged and may be abandoned in
74  * future.
75  *
76  * The routines include support for the 1-pps signal provided by some
77  * radios and connected via a level converted described in the gadget
78  * directory. The signal is captured using a serial port and one of
79  * three STREAMS modules described in the refclock_atom.c file. For the
80  * highest precision, the signal is captured using the carrier-detect
81  * line of a serial port and either the ppsclock or ppsapi streams
82  * module or some devilish ioctl() folks keep slipping in as a patch. Be
83  * advised ALL support for other than the duly standardized ppsapi
84  * interface will eventually be withdrawn.
85  */
86 #define MAXUNIT 	4	/* max units */
87 
88 #if defined(PPS) || defined(HAVE_PPSAPI)
89 int fdpps;			/* pps file descriptor */
90 #endif /* PPS HAVE_PPSAPI */
91 
92 #define FUDGEFAC	.1	/* fudge correction factor */
93 
94 /*
95  * Type/unit peer index. Used to find the peer structure for control and
96  * debugging. When all clock drivers have been converted to new style,
97  * this dissapears.
98  */
99 static struct peer *typeunit[REFCLK_MAX + 1][MAXUNIT];
100 
101 /*
102  * Forward declarations
103  */
104 #ifdef QSORT_USES_VOID_P
105 static int refclock_cmpl_fp P((const void *, const void *));
106 #else
107 static int refclock_cmpl_fp P((const double *, const double *));
108 #endif /* QSORT_USES_VOID_P */
109 static int refclock_sample P((struct refclockproc *));
110 
111 #ifdef HAVE_PPSAPI
112 extern int pps_assert;		/* capture edge 1:assert, 0:clear */
113 extern int pps_hardpps;		/* PPS kernel 1:on, 0:off */
114 #endif /* HAVE_PPSAPI */
115 
116 /*
117  * refclock_report - note the occurance of an event
118  *
119  * This routine presently just remembers the report and logs it, but
120  * does nothing heroic for the trap handler. It tries to be a good
121  * citizen and bothers the system log only if things change.
122  */
123 void
124 refclock_report(
125 	struct peer *peer,
126 	int code
127 	)
128 {
129 	struct refclockproc *pp;
130 
131 	if (!(pp = peer->procptr))
132 		return;
133 	if (code == CEVNT_BADREPLY)
134 		pp->badformat++;
135 	if (code == CEVNT_BADTIME)
136 		pp->baddata++;
137 	if (code == CEVNT_TIMEOUT)
138 		pp->noreply++;
139 	if (pp->currentstatus != code) {
140 		pp->currentstatus = code;
141 		pp->lastevent = code;
142 		if (code == CEVNT_FAULT)
143 			msyslog(LOG_ERR,
144 				"clock %s event '%s' (0x%02x)",
145 				refnumtoa(peer->srcadr.sin_addr.s_addr),
146 				ceventstr(code), code);
147 		else {
148 			NLOG(NLOG_CLOCKEVENT)
149 				msyslog(LOG_INFO,
150 				"clock %s event '%s' (0x%02x)",
151 				refnumtoa(peer->srcadr.sin_addr.s_addr),
152 				ceventstr(code), code);
153 		}
154 	}
155 #ifdef DEBUG
156 	if (debug)
157 		printf("clock %s event '%s' (0x%02x)\n",
158 			refnumtoa(peer->srcadr.sin_addr.s_addr),
159 			ceventstr(code), code);
160 #endif
161 }
162 
163 
164 /*
165  * init_refclock - initialize the reference clock drivers
166  *
167  * This routine calls each of the drivers in turn to initialize internal
168  * variables, if necessary. Most drivers have nothing to say at this
169  * point.
170  */
171 void
172 init_refclock(void)
173 {
174 	int i, j;
175 
176 	for (i = 0; i < (int)num_refclock_conf; i++) {
177 		if (refclock_conf[i]->clock_init != noentry)
178 			(refclock_conf[i]->clock_init)();
179 		for (j = 0; j < MAXUNIT; j++)
180 			typeunit[i][j] = 0;
181 	}
182 }
183 
184 
185 /*
186  * refclock_newpeer - initialize and start a reference clock
187  *
188  * This routine allocates and initializes the interface structure which
189  * supports a reference clock in the form of an ordinary NTP peer. A
190  * driver-specific support routine completes the initialization, if
191  * used. Default peer variables which identify the clock and establish
192  * its reference ID and stratum are set here. It returns one if success
193  * and zero if the clock address is invalid or already running,
194  * insufficient resources are available or the driver declares a bum
195  * rap.
196  */
197 int
198 refclock_newpeer(
199 	struct peer *peer	/* peer structure pointer */
200 	)
201 {
202 	struct refclockproc *pp;
203 	u_char clktype;
204 	int unit;
205 
206 	/*
207 	 * Check for valid clock address. If already running, shut it
208 	 * down first.
209 	 */
210 	if (!ISREFCLOCKADR(&peer->srcadr)) {
211 		msyslog(LOG_ERR,
212 			"refclock_newpeer: clock address %s invalid",
213 			ntoa(&peer->srcadr));
214 		return (0);
215 	}
216 	clktype = (u_char)REFCLOCKTYPE(&peer->srcadr);
217 	unit = REFCLOCKUNIT(&peer->srcadr);
218 	if (clktype >= num_refclock_conf || unit >= MAXUNIT ||
219 		refclock_conf[clktype]->clock_start == noentry) {
220 		msyslog(LOG_ERR,
221 			"refclock_newpeer: clock type %d invalid\n",
222 			clktype);
223 		return (0);
224 	}
225 	refclock_unpeer(peer);
226 
227 	/*
228 	 * Allocate and initialize interface structure
229 	 */
230 	if (!(pp = (struct refclockproc *)emalloc(sizeof(struct refclockproc))))
231 		return (0);
232 	memset((char *)pp, 0, sizeof(struct refclockproc));
233 	typeunit[clktype][unit] = peer;
234 	peer->procptr = pp;
235 
236 	/*
237 	 * Initialize structures
238 	 */
239 	peer->refclktype = clktype;
240 	peer->refclkunit = unit;
241 	peer->flags |= FLAG_REFCLOCK;
242 	peer->stratum = STRATUM_REFCLOCK;
243 	peer->refid = peer->srcadr.sin_addr.s_addr;
244 	peer->maxpoll = peer->minpoll;
245 
246 	pp->type = clktype;
247 	pp->timestarted = current_time;
248 
249 	/*
250 	 * If the interface has been set to any_interface, set it to the
251 	 * loopback address if we have one. This is so that peers which
252 	 * are unreachable are easy to see in the peer display.
253 	 */
254 	if (peer->dstadr == any_interface && loopback_interface != 0)
255 		peer->dstadr = loopback_interface;
256 
257 	/*
258 	 * Set peer.pmode based on the hmode. For appearances only.
259 	 */
260 	switch (peer->hmode) {
261 
262 		case MODE_ACTIVE:
263 		peer->pmode = MODE_PASSIVE;
264 		break;
265 
266 		default:
267 		peer->pmode = MODE_SERVER;
268 		break;
269 	}
270 
271 	/*
272 	 * Do driver dependent initialization. The above defaults
273 	 * can be wiggled, then finish up for consistency.
274 	 */
275 	if (!((refclock_conf[clktype]->clock_start)(unit, peer))) {
276 		free(pp);
277 		return (0);
278 	}
279 	peer->hpoll = peer->minpoll;
280 	peer->ppoll = peer->maxpoll;
281 	if (peer->stratum <= 1)
282 		peer->refid = pp->refid;
283 	else
284 		peer->refid = peer->srcadr.sin_addr.s_addr;
285 	return (1);
286 }
287 
288 
289 /*
290  * refclock_unpeer - shut down a clock
291  */
292 void
293 refclock_unpeer(
294 	struct peer *peer	/* peer structure pointer */
295 	)
296 {
297 	u_char clktype;
298 	int unit;
299 
300 	/*
301 	 * Wiggle the driver to release its resources, then give back
302 	 * the interface structure.
303 	 */
304 	if (!peer->procptr)
305 		return;
306 	clktype = peer->refclktype;
307 	unit = peer->refclkunit;
308 	if (refclock_conf[clktype]->clock_shutdown != noentry)
309 		(refclock_conf[clktype]->clock_shutdown)(unit, peer);
310 	free(peer->procptr);
311 	peer->procptr = 0;
312 }
313 
314 
315 /*
316  * refclock_transmit - simulate the transmit procedure
317  *
318  * This routine implements the NTP transmit procedure for a reference
319  * clock. This provides a mechanism to call the driver at the NTP poll
320  * interval, as well as provides a reachability mechanism to detect a
321  * broken radio or other madness.
322  */
323 void
324 refclock_transmit(
325 	struct peer *peer	/* peer structure pointer */
326 	)
327 {
328 	u_char clktype;
329 	int unit;
330 	int hpoll;
331 	u_long next;
332 
333 	clktype = peer->refclktype;
334 	unit = peer->refclkunit;
335 	peer->sent++;
336 
337 	/*
338 	 * This is a ripoff of the peer transmit routine, but
339 	 * specialized for reference clocks. We do a little less
340 	 * protocol here and call the driver-specific transmit routine.
341 	 */
342 	hpoll = peer->hpoll;
343 	next = peer->outdate;
344 	if (peer->burst == 0) {
345 		u_char oreach;
346 #ifdef DEBUG
347 		if (debug)
348 			printf("refclock_transmit: at %ld %s\n",
349 			    current_time, ntoa(&(peer->srcadr)));
350 #endif
351 
352 		/*
353 		 * Update reachability and poll variables like the
354 		 * network code.
355 		 */
356 		oreach = peer->reach;
357 		if (oreach & 0x01)
358 			peer->valid++;
359 		if (oreach & 0x80)
360 			peer->valid--;
361 				peer->reach <<= 1;
362 		if (peer->reach == 0) {
363 			if (oreach != 0) {
364 				report_event(EVNT_UNREACH, peer);
365 				peer->timereachable = current_time;
366 				peer_clear(peer);
367 			}
368 		} else {
369 			if ((oreach & 0x03) == 0) {
370 				clock_filter(peer, 0., 0., MAXDISPERSE);
371 				clock_select();
372 			}
373 			if (peer->valid <= 2) {
374 				hpoll--;
375 			} else if (peer->valid > NTP_SHIFT - 2)
376 				hpoll++;
377 			if (peer->flags & FLAG_BURST)
378 				peer->burst = NSTAGE;
379 		}
380 		next = current_time;
381 	}
382 	get_systime(&peer->xmt);
383 	if (refclock_conf[clktype]->clock_poll != noentry)
384 		(refclock_conf[clktype]->clock_poll)(unit, peer);
385 	peer->outdate = next;
386 	poll_update(peer, hpoll);
387 	if (peer->burst > 0)
388 		peer->burst--;
389 	poll_update(peer, hpoll);
390 }
391 
392 
393 /*
394  * Compare two doubles - used with qsort()
395  */
396 #ifdef QSORT_USES_VOID_P
397 static int
398 refclock_cmpl_fp(
399 	const void *p1,
400 	const void *p2
401 	)
402 {
403 	const double *dp1 = (const double *)p1;
404 	const double *dp2 = (const double *)p2;
405 
406 	if (*dp1 < *dp2)
407 		return (-1);
408 	if (*dp1 > *dp2)
409 		return (1);
410 	return (0);
411 }
412 #else
413 static int
414 refclock_cmpl_fp(
415 	const double *dp1,
416 	const double *dp2
417 	)
418 {
419 	if (*dp1 < *dp2)
420 		return (-1);
421 	if (*dp1 > *dp2)
422 		return (1);
423 	return (0);
424 }
425 #endif /* QSORT_USES_VOID_P */
426 
427 
428 /*
429  * refclock_process_offset - update median filter
430  *
431  * This routine uses the given offset and timestamps to construct a new entry in the median filter circular buffer. Samples that overflow the filter are quietly discarded.
432  */
433 void
434 refclock_process_offset(
435 	struct refclockproc *pp,
436 	l_fp offset,
437 	l_fp lastrec,
438 	double fudge
439 	)
440 {
441 	double doffset;
442 
443 	pp->lastref = offset;
444 	pp->lastrec = lastrec;
445 	pp->variance = 0;
446 	L_SUB(&offset, &lastrec);
447 	LFPTOD(&offset, doffset);
448 	SAMPLE(doffset + fudge);
449 }
450 
451 /*
452  * refclock_process - process a sample from the clock
453  *
454  * This routine converts the timecode in the form days, hours, minutes,
455  * seconds and milliseconds/microseconds to internal timestamp format,
456  * then constructs a new entry in the median filter circular buffer.
457  * Return success (1) if the data are correct and consistent with the
458  * converntional calendar.
459 */
460 int
461 refclock_process(
462 	struct refclockproc *pp
463 	)
464 {
465 	l_fp offset;
466 
467 	/*
468 	 * Compute the timecode timestamp from the days, hours, minutes,
469 	 * seconds and milliseconds/microseconds of the timecode. Use
470 	 * clocktime() for the aggregate seconds and the msec/usec for
471 	 * the fraction, when present. Note that this code relies on the
472 	 * filesystem time for the years and does not use the years of
473 	 * the timecode.
474 	 */
475 	if (!clocktime(pp->day, pp->hour, pp->minute, pp->second, GMT,
476 		pp->lastrec.l_ui, &pp->yearstart, &offset.l_ui))
477 		return (0);
478 	if (pp->usec) {
479 		TVUTOTSF(pp->usec, offset.l_uf);
480 	} else {
481 		MSUTOTSF(pp->msec, offset.l_uf);
482 	}
483 	refclock_process_offset(pp, offset, pp->lastrec,
484 	    pp->fudgetime1);
485 	return (1);
486 }
487 
488 /*
489  * refclock_sample - process a pile of samples from the clock
490  *
491  * This routine implements a recursive median filter to suppress spikes
492  * in the data, as well as determine a performance statistic. It
493  * calculates the mean offset and mean-square variance. A time
494  * adjustment fudgetime1 can be added to the final offset to compensate
495  * for various systematic errors. The routine returns the number of
496  * samples processed, which could be 0.
497  */
498 static int
499 refclock_sample(
500 	struct refclockproc *pp
501 	)
502 {
503 	int i, j, k, n;
504 	double offset, disp;
505 	double off[MAXSTAGE];
506 
507 	/*
508 	 * Copy the raw offsets and sort into ascending order. Don't do
509 	 * anything if the buffer is empty.
510 	 */
511 	if (pp->codeproc == pp->coderecv)
512 		return (0);
513 	n = 0;
514 	while (pp->codeproc != pp->coderecv)
515 		off[n++] = pp->filter[pp->codeproc++ % MAXSTAGE];
516 	if (n > 1)
517 		qsort((char *)off, n, sizeof(double), refclock_cmpl_fp);
518 
519 	/*
520 	 * Reject the furthest from the median of the samples until
521 	 * approximately 60 percent of the samples remain.
522 	 */
523 	i = 0; j = n;
524 	k = n - (n * 2) / NSTAGE;
525 	while ((j - i) > k) {
526 		offset = off[(j + i) / 2];
527 		if (off[j - 1] - offset < offset - off[i])
528 			i++;	/* reject low end */
529 		else
530 			j--;	/* reject high end */
531 	}
532 
533 	/*
534 	 * Determine the offset and variance.
535 	 */
536 	offset = disp = 0;
537 	for (; i < j; i++) {
538 		offset += off[i];
539 		disp += SQUARE(off[i]);
540 	}
541 	offset /= k;
542 	pp->offset = offset;
543 	pp->variance += disp / k - SQUARE(offset);
544 #ifdef DEBUG
545 	if (debug)
546 		printf(
547 		    "refclock_sample: n %d offset %.6f disp %.6f std %.6f\n",
548 		    n, pp->offset, pp->disp, SQRT(pp->variance));
549 #endif
550 	return (n);
551 }
552 
553 
554 /*
555  * refclock_receive - simulate the receive and packet procedures
556  *
557  * This routine simulates the NTP receive and packet procedures for a
558  * reference clock. This provides a mechanism in which the ordinary NTP
559  * filter, selection and combining algorithms can be used to suppress
560  * misbehaving radios and to mitigate between them when more than one is
561  * available for backup.
562  */
563 void
564 refclock_receive(
565 	struct peer *peer	/* peer structure pointer */
566 	)
567 {
568 	struct refclockproc *pp;
569 
570 #ifdef DEBUG
571 	if (debug)
572 		printf("refclock_receive: at %lu %s\n",
573 		    current_time, ntoa(&peer->srcadr));
574 #endif
575 
576 	/*
577 	 * Do a little sanity dance and update the peer structure. Groom
578 	 * the median filter samples and give the data to the clock
579 	 * filter.
580 	 */
581 	peer->received++;
582 	pp = peer->procptr;
583 	peer->processed++;
584 	peer->timereceived = current_time;
585 	peer->leap = pp->leap;
586 	if (peer->leap == LEAP_NOTINSYNC) {
587 		refclock_report(peer, CEVNT_FAULT);
588 		return;
589 	}
590 	if (peer->reach == 0)
591 		report_event(EVNT_REACH, peer);
592 	peer->reach |= 1;
593 	peer->reftime = peer->org = pp->lastrec;
594 	peer->rootdispersion = pp->disp + SQRT(pp->variance);
595 	get_systime(&peer->rec);
596 	if (!refclock_sample(pp))
597 		return;
598 	clock_filter(peer, pp->offset, 0., 0.);
599 	clock_select();
600 	record_peer_stats(&peer->srcadr, ctlpeerstatus(peer),
601 	    peer->offset, peer->delay, CLOCK_PHI * (current_time -
602 	    peer->epoch), SQRT(peer->variance));
603 	if (pps_control && pp->sloppyclockflag & CLK_FLAG1)
604 		pp->fudgetime1 -= pp->offset * FUDGEFAC;
605 }
606 
607 /*
608  * refclock_gtlin - groom next input line and extract timestamp
609  *
610  * This routine processes the timecode received from the clock and
611  * removes the parity bit and control characters. If a timestamp is
612  * present in the timecode, as produced by the tty_clk STREAMS module,
613  * it returns that as the timestamp; otherwise, it returns the buffer
614  *  timestamp. The routine return code is the number of characters in
615  * the line.
616  */
617 int
618 refclock_gtlin(
619 	struct recvbuf *rbufp,	/* receive buffer pointer */
620 	char *lineptr,		/* current line pointer */
621 	int bmax,		/* remaining characters in line */
622 	l_fp *tsptr 	/* pointer to timestamp returned */
623 	)
624 {
625 	char *dpt, *dpend, *dp;
626 	int i;
627 	l_fp trtmp, tstmp;
628 	char c;
629 #ifdef TIOCDCDTIMESTAMP
630 	struct timeval dcd_time;
631 #endif /* TIOCDCDTIMESTAMP */
632 #ifdef HAVE_PPSAPI
633 	pps_info_t pi;
634 	struct timespec timeout, *tsp;
635 	double a;
636 #endif /* HAVE_PPSAPI */
637 
638 	/*
639 	 * Check for the presence of a timestamp left by the tty_clock
640 	 * module and, if present, use that instead of the buffer
641 	 * timestamp captured by the I/O routines. We recognize a
642 	 * timestamp by noting its value is earlier than the buffer
643 	 * timestamp, but not more than one second earlier.
644 	 */
645 	dpt = (char *)&rbufp->recv_space;
646 	dpend = dpt + rbufp->recv_length;
647 	trtmp = rbufp->recv_time;
648 
649 #ifdef HAVE_PPSAPI
650 	timeout.tv_sec = 0;
651 	timeout.tv_nsec = 0;
652 	if ((rbufp->fd == fdpps) &&
653 	    (time_pps_fetch(fdpps, PPS_TSFMT_TSPEC, &pi, &timeout) >= 0)) {
654 		if(pps_assert)
655 			tsp = &pi.assert_timestamp;
656 		else
657 			tsp = &pi.clear_timestamp;
658 		a = tsp->tv_nsec;
659 		a /= 1e9;
660 		tstmp.l_uf =  a * 4294967296.0;
661 		tstmp.l_ui = tsp->tv_sec;
662 		tstmp.l_ui += JAN_1970;
663 		L_SUB(&trtmp, &tstmp);
664 		if (trtmp.l_ui == 0) {
665 #ifdef DEBUG
666 			if (debug > 1) {
667 				printf(
668 				    "refclock_gtlin: fd %d time_pps_fetch %s",
669 				    fdpps, lfptoa(&tstmp, 6));
670 				printf(" sigio %s\n", lfptoa(&trtmp, 6));
671 			}
672 #endif
673 			trtmp = tstmp;
674 			goto gotit;
675 		} else
676 			trtmp = rbufp->recv_time;
677 	}
678 #endif /* HAVE_PPSAPI */
679 #ifdef TIOCDCDTIMESTAMP
680 	if(ioctl(rbufp->fd, TIOCDCDTIMESTAMP, &dcd_time) != -1) {
681 		TVTOTS(&dcd_time, &tstmp);
682 		tstmp.l_ui += JAN_1970;
683 		L_SUB(&trtmp, &tstmp);
684 		if (trtmp.l_ui == 0) {
685 #ifdef DEBUG
686 			if (debug > 1) {
687 				printf(
688 				    "refclock_gtlin: fd %d DCDTIMESTAMP %s",
689 				    rbufp->fd, lfptoa(&tstmp, 6));
690 				printf(" sigio %s\n", lfptoa(&trtmp, 6));
691 			}
692 #endif
693 			trtmp = tstmp;
694 			goto gotit;
695 		} else
696 			trtmp = rbufp->recv_time;
697 	}
698 	else
699 	/* XXX fallback to old method if kernel refuses TIOCDCDTIMESTAMP */
700 #endif  /* TIOCDCDTIMESTAMP */
701 	if (dpend >= dpt + 8) {
702 		if (buftvtots(dpend - 8, &tstmp)) {
703 			L_SUB(&trtmp, &tstmp);
704 			if (trtmp.l_ui == 0) {
705 #ifdef DEBUG
706 				if (debug > 1) {
707 					printf(
708 					    "refclock_gtlin: fd %d ldisc %s",
709 					    rbufp->fd, lfptoa(&trtmp, 6));
710 					get_systime(&trtmp);
711 					L_SUB(&trtmp, &tstmp);
712 					printf(" sigio %s\n", lfptoa(&trtmp, 6));
713 				}
714 #endif
715 				dpend -= 8;
716 				trtmp = tstmp;
717 			} else
718 				trtmp = rbufp->recv_time;
719 		}
720 	}
721 
722 #if defined(HAVE_PPSAPI) || defined(TIOCDCDTIMESTAMP)
723 gotit:
724 #endif
725 	/*
726 	 * Edit timecode to remove control chars. Don't monkey with the
727 	 * line buffer if the input buffer contains no ASCII printing
728 	 * characters.
729 	 */
730 	if (dpend - dpt > bmax - 1)
731 		dpend = dpt + bmax - 1;
732 	for (dp = lineptr; dpt < dpend; dpt++) {
733 		c = *dpt & 0x7f;
734 		if (c >= ' ')
735 			*dp++ = c;
736 	}
737 	i = dp - lineptr;
738 	if (i > 0)
739 		*dp = '\0';
740 #ifdef DEBUG
741 	if (debug > 1 && i > 0)
742 		printf("refclock_gtlin: fd %d time %s timecode %d %s\n",
743 		    rbufp->fd, ulfptoa(&trtmp, 6), i, lineptr);
744 #endif
745 	*tsptr = trtmp;
746 	return (i);
747 }
748 
749 /*
750  * The following code does not apply to WINNT & VMS ...
751  */
752 #if !defined SYS_VXWORKS && !defined SYS_WINNT
753 #if defined(HAVE_TERMIOS) || defined(HAVE_SYSV_TTYS) || defined(HAVE_BSD_TTYS)
754 
755 /*
756  * refclock_open - open serial port for reference clock
757  *
758  * This routine opens a serial port for I/O and sets default options. It
759  * returns the file descriptor if success and zero if failure.
760  */
761 int
762 refclock_open(
763 	char *dev,		/* device name pointer */
764 	int speed,		/* serial port speed (code) */
765 	int lflags		/* line discipline flags */
766 	)
767 {
768 	int fd, i;
769 	int flags;
770 #ifdef HAVE_TERMIOS
771 	struct termios ttyb, *ttyp;
772 #endif /* HAVE_TERMIOS */
773 #ifdef HAVE_SYSV_TTYS
774 	struct termio ttyb, *ttyp;
775 #endif /* HAVE_SYSV_TTYS */
776 #ifdef HAVE_BSD_TTYS
777 	struct sgttyb ttyb, *ttyp;
778 #endif /* HAVE_BSD_TTYS */
779 #ifdef TIOCMGET
780 	u_long ltemp;
781 #endif /* TIOCMGET */
782 
783 	/*
784 	 * Open serial port and set default options
785 	 */
786 	flags = lflags;
787 	if (strcmp(dev, pps_device) == 0)
788 		flags |= LDISC_PPS;
789 #ifdef O_NONBLOCK
790 	fd = open(dev, O_RDWR | O_NONBLOCK, 0777);
791 #else
792 	fd = open(dev, O_RDWR, 0777);
793 #endif /* O_NONBLOCK */
794 	if (fd == -1) {
795 		msyslog(LOG_ERR, "refclock_open: %s: %m", dev);
796 		return (0);
797 	}
798 
799 	/*
800 	 * The following sections initialize the serial line port in
801 	 * canonical (line-oriented) mode and set the specified line
802 	 * speed, 8 bits and no parity. The modem control, break, erase
803 	 * and kill functions are normally disabled. There is a
804 	 * different section for each terminal interface, as selected at
805 	 * compile time.
806 	 */
807 	ttyp = &ttyb;
808 
809 #ifdef HAVE_TERMIOS
810 	/*
811 	 * POSIX serial line parameters (termios interface)
812 	 */
813 	if (tcgetattr(fd, ttyp) < 0) {
814 		msyslog(LOG_ERR,
815 			"refclock_open: fd %d tcgetattr: %m", fd);
816 		return (0);
817 	}
818 
819 	/*
820 	 * Set canonical mode and local connection; set specified speed,
821 	 * 8 bits and no parity; map CR to NL; ignore break.
822 	 */
823 	ttyp->c_iflag = IGNBRK | IGNPAR | ICRNL;
824 	ttyp->c_oflag = 0;
825 	ttyp->c_cflag = CS8 | CLOCAL | CREAD;
826 	(void)cfsetispeed(&ttyb, (u_int)speed);
827 	(void)cfsetospeed(&ttyb, (u_int)speed);
828 	ttyp->c_lflag = ICANON;
829 	for (i = 0; i < NCCS; ++i)
830 	{
831 		ttyp->c_cc[i] = '\0';
832 	}
833 
834 	/*
835 	 * Some special cases
836 	 */
837 	if (flags & LDISC_RAW) {
838 		ttyp->c_iflag = 0;
839 		ttyp->c_lflag = 0;
840 		ttyp->c_cc[VMIN] = 1;
841 	}
842 #if defined(TIOCMGET) && !defined(SCO5_CLOCK)
843 	/*
844 	 * If we have modem control, check to see if modem leads are
845 	 * active; if so, set remote connection. This is necessary for
846 	 * the kernel pps mods to work.
847 	 */
848 	ltemp = 0;
849 	if (ioctl(fd, TIOCMGET, (char *)&ltemp) < 0)
850 		msyslog(LOG_ERR,
851 			"refclock_open: fd %d TIOCMGET failed: %m", fd);
852 #ifdef DEBUG
853 	if (debug)
854 		printf("refclock_open: fd %d modem status 0x%lx\n",
855 		    fd, ltemp);
856 #endif
857 	if (ltemp & TIOCM_DSR)
858 		ttyp->c_cflag &= ~CLOCAL;
859 #endif /* TIOCMGET */
860 	if (tcsetattr(fd, TCSANOW, ttyp) < 0) {
861 		msyslog(LOG_ERR,
862 		    "refclock_open: fd %d TCSANOW failed: %m", fd);
863 		return (0);
864 	}
865 	if (tcflush(fd, TCIOFLUSH) < 0) {
866 		msyslog(LOG_ERR,
867 		    "refclock_open: fd %d TCIOFLUSH failed: %m", fd);
868 		return (0);
869 	}
870 #endif /* HAVE_TERMIOS */
871 
872 #ifdef HAVE_SYSV_TTYS
873 
874 	/*
875 	 * System V serial line parameters (termio interface)
876 	 *
877 	 */
878 	if (ioctl(fd, TCGETA, ttyp) < 0) {
879 		msyslog(LOG_ERR,
880 		    "refclock_open: fd %d TCGETA failed: %m", fd);
881 		return (0);
882 	}
883 
884 	/*
885 	 * Set canonical mode and local connection; set specified speed,
886 	 * 8 bits and no parity; map CR to NL; ignore break.
887 	 */
888 	ttyp->c_iflag = IGNBRK | IGNPAR | ICRNL;
889 	ttyp->c_oflag = 0;
890 	ttyp->c_cflag = speed | CS8 | CLOCAL | CREAD;
891 	ttyp->c_lflag = ICANON;
892 	ttyp->c_cc[VERASE] = ttyp->c_cc[VKILL] = '\0';
893 
894 	/*
895 	 * Some special cases
896 	 */
897 	if (flags & LDISC_RAW) {
898 		ttyp->c_iflag = 0;
899 		ttyp->c_lflag = 0;
900 	}
901 #ifdef TIOCMGET
902 	/*
903 	 * If we have modem control, check to see if modem leads are
904 	 * active; if so, set remote connection. This is necessary for
905 	 * the kernel pps mods to work.
906 	 */
907 	ltemp = 0;
908 	if (ioctl(fd, TIOCMGET, (char *)&ltemp) < 0)
909 		msyslog(LOG_ERR,
910 		    "refclock_open: fd %d TIOCMGET failed: %m", fd);
911 #ifdef DEBUG
912 	if (debug)
913 		printf("refclock_open: fd %d modem status %lx\n",
914 		    fd, ltemp);
915 #endif
916 	if (ltemp & TIOCM_DSR)
917 		ttyp->c_cflag &= ~CLOCAL;
918 #endif /* TIOCMGET */
919 	if (ioctl(fd, TCSETA, ttyp) < 0) {
920 		msyslog(LOG_ERR,
921 		    "refclock_open: fd %d TCSETA failed: %m", fd);
922 		return (0);
923 	}
924 #endif /* HAVE_SYSV_TTYS */
925 
926 #ifdef HAVE_BSD_TTYS
927 
928 	/*
929 	 * 4.3bsd serial line parameters (sgttyb interface)
930 	 */
931 	if (ioctl(fd, TIOCGETP, (char *)ttyp) < 0) {
932 		msyslog(LOG_ERR,
933 		    "refclock_open: fd %d TIOCGETP %m", fd);
934 		return (0);
935 	}
936 	ttyp->sg_ispeed = ttyp->sg_ospeed = speed;
937 	ttyp->sg_flags = EVENP | ODDP | CRMOD;
938 	if (ioctl(fd, TIOCSETP, (char *)ttyp) < 0) {
939 		msyslog(LOG_ERR,
940 		    "refclock_open: TIOCSETP failed: %m");
941 		return (0);
942 	}
943 #endif /* HAVE_BSD_TTYS */
944 	if (!refclock_ioctl(fd, flags)) {
945 		(void)close(fd);
946 		msyslog(LOG_ERR,
947 		    "refclock_open: fd %d ioctl failed: %m", fd);
948 		return (0);
949 	}
950 	return (fd);
951 }
952 #endif /* HAVE_TERMIOS || HAVE_SYSV_TTYS || HAVE_BSD_TTYS */
953 #endif /* SYS_VXWORKS SYS_WINNT */
954 
955 /*
956  * refclock_ioctl - set serial port control functions
957  *
958  * This routine attempts to hide the internal, system-specific details
959  * of serial ports. It can handle POSIX (termios), SYSV (termio) and BSD
960  * (sgtty) interfaces with varying degrees of success. The routine sets
961  * up optional features such as tty_clk, ppsclock and ppsapi, as well as
962  * their many other variants. The routine returns 1 if success and 0 if
963  * failure.
964  */
965 int
966 refclock_ioctl(
967 	int fd, 		/* file descriptor */
968 	int flags		/* line discipline flags */
969 	)
970 {
971 	/* simply return 1 if no UNIX line discipline is supported */
972 #if !defined SYS_VXWORKS && !defined SYS_WINNT
973 #if defined(HAVE_TERMIOS) || defined(HAVE_SYSV_TTYS) || defined(HAVE_BSD_TTYS)
974 
975 #ifdef TTYCLK
976 #ifdef HAVE_TERMIOS
977 	struct termios ttyb, *ttyp;
978 #endif /* HAVE_TERMIOS */
979 #ifdef HAVE_SYSV_TTYS
980 	struct termio ttyb, *ttyp;
981 #endif /* HAVE_SYSV_TTYS */
982 #ifdef HAVE_BSD_TTYS
983 	struct sgttyb ttyb, *ttyp;
984 #endif /* HAVE_BSD_TTYS */
985 #endif /* TTYCLK */
986 
987 #ifdef DEBUG
988 	if (debug)
989 		printf("refclock_ioctl: fd %d flags 0x%x\n", fd, flags);
990 #endif
991 
992 	/*
993 	 * The following sections select optional features, such as
994 	 * modem control, PPS capture and so forth. Some require
995 	 * specific operating system support in the form of STREAMS
996 	 * modules, which can be loaded and unloaded at run time without
997 	 * rebooting the kernel. The STREAMS modules require System
998 	 * V STREAMS support. The checking frenzy is attenuated here,
999 	 * since the device is already open.
1000 	 *
1001 	 * Note that the tty_clk and ppsclock modules are optional; if
1002 	 * configured and unavailable, the dang thing still works, but
1003 	 * the accuracy improvement using them will not be available.
1004 	 * The only known implmentations of these moldules are specific
1005 	 * to SunOS 4.x. Use the ppsclock module ONLY with Sun baseboard
1006 	 * ttya or ttyb. Using it with the SPIF multipexor crashes the
1007 	 * kernel.
1008 	 *
1009 	 * The preferred way to capture PPS timestamps is using the
1010 	 * ppsapi interface, which is machine independent. The SunOS 4.x
1011 	 * and Digital Unix 4.x interfaces use STREAMS modules and
1012 	 * support both the ppsapi specification and ppsclock
1013 	 * functionality, but other systems may vary widely.
1014 	 */
1015 	if (flags == 0)
1016 		return (1);
1017 #if !(defined(HAVE_TERMIOS) || defined(HAVE_BSD_TTYS))
1018 	if (flags & (LDISC_CLK | LDISC_PPS | LDISC_ACTS)) {
1019 		msyslog(LOG_ERR,
1020 			"refclock_ioctl: unsupported terminal interface");
1021 		return (0);
1022 	}
1023 #endif /* HAVE_TERMIOS HAVE_BSD_TTYS */
1024 #ifdef TTYCLK
1025 	ttyp = &ttyb;
1026 #endif /* TTYCLK */
1027 
1028 	/*
1029 	 * The following features may or may not require System V
1030 	 * STREAMS support, depending on the particular implementation.
1031 	 */
1032 #if defined(TTYCLK)
1033 	/*
1034 	 * The TTYCLK option provides timestamping at the driver level.
1035 	 * It requires the tty_clk streams module and System V STREAMS
1036 	 * support. If not available, don't complain.
1037 	 */
1038 	if (flags & (LDISC_CLK | LDISC_CLKPPS | LDISC_ACTS)) {
1039 		int rval = 0;
1040 
1041 		if (ioctl(fd, I_PUSH, "clk") < 0) {
1042 			msyslog(LOG_NOTICE,
1043 			    "refclock_ioctl: I_PUSH clk failed: %m");
1044 		} else {
1045 			char *str;
1046 
1047 			if (flags & LDISC_CLKPPS)
1048 				str = "\377";
1049 			else if (flags & LDISC_ACTS)
1050 				str = "*";
1051 			else
1052 				str = "\n";
1053 #ifdef CLK_SETSTR
1054 			if ((rval = ioctl(fd, CLK_SETSTR, str)) < 0)
1055 				msyslog(LOG_ERR,
1056 				    "refclock_ioctl: CLK_SETSTR failed: %m");
1057 			if (debug)
1058 				printf("refclock_ioctl: fd %d CLK_SETSTR %d str %s\n",
1059 				    fd, rval, str);
1060 #endif
1061 		}
1062 	}
1063 #endif /* TTYCLK */
1064 
1065 #if defined(PPS) && !defined(HAVE_PPSAPI)
1066 	/*
1067 	 * The PPS option provides timestamping at the driver level.
1068 	 * It uses a 1-pps signal and level converter (gadget box) and
1069 	 * requires the ppsclock streams module and System V STREAMS
1070 	 * support. This option has been superseded by the ppsapi
1071 	 * option and may be withdrawn in future.
1072 	 */
1073 	if (flags & LDISC_PPS) {
1074 		int rval = 0;
1075 #ifdef HAVE_TIOCSPPS		/* Solaris */
1076 		int one = 1;
1077 #endif /* HAVE_TIOCSPPS */
1078 
1079 		if (fdpps > 0) {
1080 			msyslog(LOG_ERR,
1081 				"refclock_ioctl: PPS already configured");
1082 			return (0);
1083 		}
1084 #ifdef HAVE_TIOCSPPS		/* Solaris */
1085 		if (ioctl(fd, TIOCSPPS, &one) < 0) {
1086 			msyslog(LOG_NOTICE,
1087 				"refclock_ioctl: TIOCSPPS failed: %m");
1088 			return (0);
1089 		}
1090 		if (debug)
1091 			printf("refclock_ioctl: fd %d TIOCSPPS %d\n",
1092 			    fd, rval);
1093 #else
1094 		if (ioctl(fd, I_PUSH, "ppsclock") < 0) {
1095 			msyslog(LOG_NOTICE,
1096 				"refclock_ioctl: I_PUSH ppsclock failed: %m");
1097 			return (0);
1098 		}
1099 		if (debug)
1100 			printf("refclock_ioctl: fd %d ppsclock %d\n",
1101 			    fd, rval);
1102 #endif /* not HAVE_TIOCSPPS */
1103 		fdpps = fd;
1104 	}
1105 #endif /* PPS HAVE_PPSAPI */
1106 
1107 #ifdef HAVE_PPSAPI
1108 	/*
1109 	 * The PPSAPI option provides timestamping at the driver level.
1110 	 * It uses a 1-pps signal and level converter (gadget box) and
1111 	 * requires ppsapi compiled into the kernel on non STREAMS
1112 	 * systems. This is the preferred way to capture PPS timestamps
1113 	 * and is expected to become an IETF cross-platform standard.
1114 	 */
1115 	if (flags & (LDISC_PPS | LDISC_CLKPPS)) {
1116 		pps_params_t pp;
1117 		int mode, temp;
1118 		pps_handle_t handle;
1119 
1120 		memset((char *)&pp, 0, sizeof(pp));
1121 		if (fdpps > 0) {
1122 			msyslog(LOG_ERR,
1123 			    "refclock_ioctl: ppsapi already configured");
1124 			return (0);
1125 		}
1126 		if (time_pps_create(fd, &handle) < 0) {
1127 			msyslog(LOG_ERR,
1128 			    "refclock_ioctl: time_pps_create failed: %m");
1129 			return (0);
1130 		}
1131 		if (time_pps_getcap(handle, &mode) < 0) {
1132 			msyslog(LOG_ERR,
1133 			    "refclock_ioctl: time_pps_getcap failed: %m");
1134 			return (0);
1135 		}
1136 		pp.mode = mode & PPS_CAPTUREBOTH;
1137 		if (time_pps_setparams(handle, &pp) < 0) {
1138 			msyslog(LOG_ERR,
1139 			    "refclock_ioctl: time_pps_setparams failed: %m");
1140 			return (0);
1141 		}
1142 		if (!pps_hardpps)
1143 			temp = 0;
1144 		else if (pps_assert)
1145 			temp = mode & PPS_CAPTUREASSERT;
1146 		else
1147 			temp = mode & PPS_CAPTURECLEAR;
1148 		if (time_pps_kcbind(handle, PPS_KC_HARDPPS, temp,
1149 		    PPS_TSFMT_TSPEC) < 0) {
1150 			msyslog(LOG_ERR,
1151 			    "refclock_ioctl: time_pps_kcbind failed: %m");
1152 			return (0);
1153 		}
1154 		(void)time_pps_getparams(handle, &pp);
1155 		fdpps = (int)handle;
1156 		if (debug)
1157 			printf(
1158 			    "refclock_ioctl: fd %d ppsapi vers %d mode 0x%x cap 0x%x\n",
1159 			    fdpps, pp.api_version, pp.mode, mode);
1160 	}
1161 #endif /* HAVE_PPSAPI */
1162 #endif /* HAVE_TERMIOS || HAVE_SYSV_TTYS || HAVE_BSD_TTYS */
1163 #endif /* SYS_VXWORKS SYS_WINNT */
1164 	return (1);
1165 }
1166 
1167 /*
1168  * refclock_control - set and/or return clock values
1169  *
1170  * This routine is used mainly for debugging. It returns designated
1171  * values from the interface structure that can be displayed using
1172  * ntpdc and the clockstat command. It can also be used to initialize
1173  * configuration variables, such as fudgetimes, fudgevalues, reference
1174  * ID and stratum.
1175  */
1176 void
1177 refclock_control(
1178 	struct sockaddr_in *srcadr,
1179 	struct refclockstat *in,
1180 	struct refclockstat *out
1181 	)
1182 {
1183 	struct peer *peer;
1184 	struct refclockproc *pp;
1185 	u_char clktype;
1186 	int unit;
1187 
1188 	/*
1189 	 * Check for valid address and running peer
1190 	 */
1191 	if (!ISREFCLOCKADR(srcadr))
1192 		return;
1193 	clktype = (u_char)REFCLOCKTYPE(srcadr);
1194 	unit = REFCLOCKUNIT(srcadr);
1195 	if (clktype >= num_refclock_conf || unit >= MAXUNIT)
1196 		return;
1197 	if (!(peer = typeunit[clktype][unit]))
1198 		return;
1199 	pp = peer->procptr;
1200 
1201 	/*
1202 	 * Initialize requested data
1203 	 */
1204 	if (in != 0) {
1205 		if (in->haveflags & CLK_HAVETIME1)
1206 			pp->fudgetime1 = in->fudgetime1;
1207 		if (in->haveflags & CLK_HAVETIME2)
1208 			pp->fudgetime2 = in->fudgetime2;
1209 		if (in->haveflags & CLK_HAVEVAL1)
1210 			peer->stratum = (u_char) in->fudgeval1;
1211 		if (in->haveflags & CLK_HAVEVAL2)
1212 			pp->refid = in->fudgeval2;
1213 		if (peer->stratum <= 1)
1214 			peer->refid = pp->refid;
1215 		else
1216 			peer->refid = peer->srcadr.sin_addr.s_addr;
1217 		if (in->haveflags & CLK_HAVEFLAG1) {
1218 			pp->sloppyclockflag &= ~CLK_FLAG1;
1219 			pp->sloppyclockflag |= in->flags & CLK_FLAG1;
1220 		}
1221 		if (in->haveflags & CLK_HAVEFLAG2) {
1222 			pp->sloppyclockflag &= ~CLK_FLAG2;
1223 			pp->sloppyclockflag |= in->flags & CLK_FLAG2;
1224 		}
1225 		if (in->haveflags & CLK_HAVEFLAG3) {
1226 			pp->sloppyclockflag &= ~CLK_FLAG3;
1227 			pp->sloppyclockflag |= in->flags & CLK_FLAG3;
1228 		}
1229 		if (in->haveflags & CLK_HAVEFLAG4) {
1230 			pp->sloppyclockflag &= ~CLK_FLAG4;
1231 			pp->sloppyclockflag |= in->flags & CLK_FLAG4;
1232 		}
1233 	}
1234 
1235 	/*
1236 	 * Readback requested data
1237 	 */
1238 	if (out != 0) {
1239 		out->haveflags = CLK_HAVETIME1 | CLK_HAVEVAL1 |
1240 			CLK_HAVEVAL2 | CLK_HAVEFLAG4;
1241 		out->fudgetime1 = pp->fudgetime1;
1242 		out->fudgetime2 = pp->fudgetime2;
1243 		out->fudgeval1 = peer->stratum;
1244 		out->fudgeval2 = pp->refid;
1245 		out->flags = (u_char) pp->sloppyclockflag;
1246 
1247 		out->timereset = current_time - pp->timestarted;
1248 		out->polls = pp->polls;
1249 		out->noresponse = pp->noreply;
1250 		out->badformat = pp->badformat;
1251 		out->baddata = pp->baddata;
1252 
1253 		out->lastevent = pp->lastevent;
1254 		out->currentstatus = pp->currentstatus;
1255 		out->type = pp->type;
1256 		out->clockdesc = pp->clockdesc;
1257 		out->lencode = pp->lencode;
1258 		out->p_lastcode = pp->a_lastcode;
1259 	}
1260 
1261 	/*
1262 	 * Give the stuff to the clock
1263 	 */
1264 	if (refclock_conf[clktype]->clock_control != noentry)
1265 		(refclock_conf[clktype]->clock_control)(unit, in, out, peer);
1266 }
1267 
1268 
1269 /*
1270  * refclock_buginfo - return debugging info
1271  *
1272  * This routine is used mainly for debugging. It returns designated
1273  * values from the interface structure that can be displayed using
1274  * ntpdc and the clkbug command.
1275  */
1276 void
1277 refclock_buginfo(
1278 	struct sockaddr_in *srcadr, /* clock address */
1279 	struct refclockbug *bug /* output structure */
1280 	)
1281 {
1282 	struct peer *peer;
1283 	struct refclockproc *pp;
1284 	u_char clktype;
1285 	int unit;
1286 	int i;
1287 
1288 	/*
1289 	 * Check for valid address and peer structure
1290 	 */
1291 	if (!ISREFCLOCKADR(srcadr))
1292 		return;
1293 	clktype = (u_char) REFCLOCKTYPE(srcadr);
1294 	unit = REFCLOCKUNIT(srcadr);
1295 	if (clktype >= num_refclock_conf || unit >= MAXUNIT)
1296 		return;
1297 	if (!(peer = typeunit[clktype][unit]))
1298 		return;
1299 	pp = peer->procptr;
1300 
1301 	/*
1302 	 * Copy structure values
1303 	 */
1304 	bug->nvalues = 8;
1305 	bug->svalues = 0x0000003f;
1306 	bug->values[0] = pp->year;
1307 	bug->values[1] = pp->day;
1308 	bug->values[2] = pp->hour;
1309 	bug->values[3] = pp->minute;
1310 	bug->values[4] = pp->second;
1311 	bug->values[5] = pp->msec;
1312 	bug->values[6] = pp->yearstart;
1313 	bug->values[7] = pp->coderecv;
1314 	bug->stimes = 0xfffffffc;
1315 	bug->times[0] = pp->lastref;
1316 	bug->times[1] = pp->lastrec;
1317 	for (i = 2; i < (int)bug->ntimes; i++)
1318 		DTOLFP(pp->filter[i - 2], &bug->times[i]);
1319 
1320 	/*
1321 	 * Give the stuff to the clock
1322 	 */
1323 	if (refclock_conf[clktype]->clock_buginfo != noentry)
1324 		(refclock_conf[clktype]->clock_buginfo)(unit, bug, peer);
1325 }
1326 
1327 #endif /* REFCLOCK */
1328