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