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