1/*
2 * refclock_acts - clock driver for the NIST/USNO/PTB/NPL Computer Time
3 *	Services
4 */
5#ifdef HAVE_CONFIG_H
6#include <config.h>
7#endif
8
9#if defined(REFCLOCK) && defined(CLOCK_ACTS)
10
11#include "ntpd.h"
12#include "ntp_io.h"
13#include "ntp_unixtime.h"
14#include "ntp_refclock.h"
15#include "ntp_stdlib.h"
16#include "ntp_control.h"
17
18#include <stdio.h>
19#include <ctype.h>
20#ifdef HAVE_SYS_IOCTL_H
21# include <sys/ioctl.h>
22#endif /* HAVE_SYS_IOCTL_H */
23
24/*
25 * This driver supports the US (NIST, USNO) and European (PTB, NPL,
26 * etc.) modem time services, as well as Spectracom GPS and WWVB
27 * receivers connected via a modem. The driver periodically dials a
28 * number from a telephone list, receives the timecode data and
29 * calculates the local clock correction. It is designed primarily for
30 * use as backup when neither a radio clock nor connectivity to Internet
31 * time servers is available.
32 *
33 * This driver requires a modem with a Hayes-compatible command set and
34 * control over the modem data terminal ready (DTR) control line. The
35 * modem setup string is hard-coded in the driver and may require
36 * changes for nonstandard modems or special circumstances.
37 *
38 * When enabled, the calling program dials the first number in the
39 * phones file. If that call fails, it dials the second number and
40 * so on. The phone number is specified by the Hayes ATDT prefix
41 * followed by the number itself, including the long-distance prefix
42 * and delay code, if necessary. The calling program is enabled
43 * when (a) fudge flag1 is set by ntpdc, (b) at each poll interval
44 * when no other synchronization sources are present, and (c) at each
45 * poll interval whether or not other synchronization sources are
46 * present. The calling program disconnects if (a) the called party
47 * is busy or does not answer, (b) the called party disconnects
48 * before a sufficient nuimber of timecodes have been received.
49 *
50 * The driver is transparent to each of the modem time services and
51 * Spectracom radios. It selects the parsing algorithm depending on the
52 * message length. There is some hazard should the message be corrupted.
53 * However, the data format is checked carefully and only if all checks
54 * succeed is the message accepted. Corrupted lines are discarded
55 * without complaint.
56 *
57 * Fudge controls
58 *
59 * flag1	force a call in manual mode
60 * flag2	enable port locking (not verified)
61 * flag3	not used
62 * flag4	not used
63 *
64 * time1	offset adjustment (s)
65 *
66 * Ordinarily, the serial port is connected to a modem and the phones
67 * list is defined. If no phones list is defined, the port can be
68 * connected directly to a device or another computer. In this case the
69 * driver will send a single character 'T' at each poll event. If
70 * fudge flag2 is enabled, port locking allows the modem to be shared
71 * when not in use by this driver.
72 */
73/*
74 * National Institute of Science and Technology (NIST)
75 *
76 * Phone: (303) 494-4774 (Boulder, CO); (808) 335-4721 (Hawaii)
77 *
78 * Data Format
79 *
80 * National Institute of Standards and Technology
81 * Telephone Time Service, Generator 3B
82 * Enter question mark "?" for HELP
83 *                         D  L D
84 *  MJD  YR MO DA H  M  S  ST S UT1 msADV        <OTM>
85 * 47999 90-04-18 21:39:15 50 0 +.1 045.0 UTC(NIST) *<CR><LF>
86 * ...
87 *
88 * MJD, DST, DUT1 and UTC are not used by this driver. The "*" or "#" is
89 * the on-time markers echoed by the driver and used by NIST to measure
90 * and correct for the propagation delay. Note: the ACTS timecode has
91 * recently been changed to eliminate the * on-time indicator. The
92 * reason for this and the long term implications are not clear.
93 *
94 * US Naval Observatory (USNO)
95 *
96 * Phone: (202) 762-1594 (Washington, DC); (719) 567-6742 (Boulder, CO)
97 *
98 * Data Format (two lines, repeating at one-second intervals)
99 *
100 * jjjjj nnn hhmmss UTC<CR><LF>
101 * *<CR><LF>
102 *
103 * jjjjj	modified Julian day number (not used)
104 * nnn		day of year
105 * hhmmss	second of day
106 * *		on-time marker for previous timecode
107 * ...
108 *
109 * USNO does not correct for the propagation delay. A fudge time1 of
110 * about .06 s is advisable.
111 *
112 * European Services (PTB, NPL, etc.)
113 *
114 * PTB: +49 531 512038 (Germany)
115 * NPL: 0906 851 6333 (UK only)
116 *
117 * Data format (see the documentation for phone numbers and formats.)
118 *
119 * 1995-01-23 20:58:51 MEZ  10402303260219950123195849740+40000500<CR><LF>
120 *
121 * Spectracom GPS and WWVB Receivers
122 *
123 * If a modem is connected to a Spectracom receiver, this driver will
124 * call it up and retrieve the time in one of two formats. As this
125 * driver does not send anything, the radio will have to either be
126 * configured in continuous mode or be polled by another local driver.
127 */
128/*
129 * Interface definitions
130 */
131#define	DEVICE		"/dev/acts%d" /* device name and unit */
132#define	SPEED232	B19200	/* uart speed (19200 bps) */
133#define	PRECISION	(-10)	/* precision assumed (about 1 ms) */
134#define LOCKFILE	"/var/spool/lock/LCK..cua%d"
135#define DESCRIPTION	"Automated Computer Time Service" /* WRU */
136#define REFID		"NONE"	/* default reference ID */
137#define MSGCNT		20	/* max message count */
138#define	MAXPHONE	10	/* max number of phone numbers */
139
140/*
141 * Calling program modes (mode)
142 */
143#define MODE_BACKUP	0	/* backup mode */
144#define MODE_AUTO	1	/* automatic mode */
145#define MODE_MANUAL	2	/* manual mode */
146
147/*
148 * Service identifiers (message length)
149 */
150#define REFACTS		"NIST"	/* NIST reference ID */
151#define LENACTS		50	/* NIST format A */
152#define REFUSNO		"USNO"	/* USNO reference ID */
153#define LENUSNO		20	/* USNO */
154#define REFPTB		"PTB\0"	/* PTB/NPL reference ID */
155#define LENPTB		78	/* PTB/NPL format */
156#define REFWWVB		"WWVB"	/* WWVB reference ID */
157#define	LENWWVB0	22	/* WWVB format 0 */
158#define	LENWWVB2	24	/* WWVB format 2 */
159#define LF		0x0a	/* ASCII LF */
160
161/*
162 * Modem setup strings. These may have to be changed for
163 * some modems.
164 *
165 * AT	command prefix
166 * B1	US answer tone
167 * &C0	disable carrier detect
168 * &D2	hang up and return to command mode on DTR transition
169 * E0	modem command echo disabled
170 * L1	set modem speaker volume to low level
171 * M1	speaker enabled until carrier detect
172 * Q0	return result codes
173 * V1	return result codes as English words
174 * Y1	enable long-space disconnect
175 */
176const char def_modem_setup[] = "ATB1&C0&D2E0L1M1Q0V1Y1";
177const char *modem_setup = def_modem_setup;
178
179/*
180 * Timeouts (all in seconds)
181 */
182#define SETUP		3	/* setup timeout */
183#define	REDIAL		30	/* redial timeout */
184#define ANSWER		60	/* answer timeout */
185#define TIMECODE	60	/* message timeout */
186#define	MAXCODE		20	/* max timecodes */
187
188/*
189 * State machine codes
190 */
191typedef enum {
192	S_IDLE,			/* wait for poll */
193	S_SETUP,		/* send modem setup */
194	S_CONNECT,		/* wait for answer */
195	S_MSG			/* wait for timecode */
196} teModemState;
197
198/*
199 * Unit control structure
200 */
201struct actsunit {
202	int	unit;		/* unit number */
203	int	state;		/* the first one was Delaware */
204	int	timer;		/* timeout counter */
205	int	retry;		/* retry index */
206	int	msgcnt;		/* count of messages received */
207	l_fp	tstamp;		/* on-time timestamp */
208	char	*bufptr;	/* next incoming char stored here */
209	char	buf[BMAX];	/* bufptr roams within buf[] */
210};
211
212/*
213 * Function prototypes
214 */
215static	int	acts_start	(int, struct peer *);
216static	void	acts_shutdown	(int, struct peer *);
217static	void	acts_receive	(struct recvbuf *);
218static	void	acts_message	(struct peer *, const char *);
219static	void	acts_timecode	(struct peer *, const char *);
220static	void	acts_poll	(int, struct peer *);
221static	void	acts_timeout	(struct peer *, teModemState);
222static	void	acts_timer	(int, struct peer *);
223static	void	acts_close	(struct peer *);
224
225/*
226 * Transfer vector (conditional structure name)
227 */
228struct refclock refclock_acts = {
229	acts_start,		/* start up driver */
230	acts_shutdown,		/* shut down driver */
231	acts_poll,		/* transmit poll message */
232	noentry,		/* not used */
233	noentry,		/* not used */
234	noentry,		/* not used */
235	acts_timer		/* housekeeping timer */
236};
237
238/*
239 * Initialize data for processing
240 */
241static int
242acts_start(
243	int	unit,
244	struct peer *peer
245	)
246{
247	struct actsunit *up;
248	struct refclockproc *pp;
249	const char *setup;
250
251	/*
252	 * Allocate and initialize unit structure
253	 */
254	up = emalloc_zero(sizeof(struct actsunit));
255	up->unit = unit;
256	pp = peer->procptr;
257	pp->unitptr = up;
258	pp->io.clock_recv = acts_receive;
259	pp->io.srcclock = peer;
260	pp->io.datalen = 0;
261	pp->io.fd = -1;
262
263	/*
264	 * Initialize miscellaneous variables
265	 */
266	peer->precision = PRECISION;
267	pp->clockdesc = DESCRIPTION;
268	memcpy(&pp->refid, REFID, 4);
269	peer->sstclktype = CTL_SST_TS_TELEPHONE;
270	up->bufptr = up->buf;
271	if (def_modem_setup == modem_setup) {
272		setup = get_ext_sys_var("modemsetup");
273		if (setup != NULL)
274			modem_setup = estrdup(setup);
275	}
276
277	return (1);
278}
279
280
281/*
282 * acts_shutdown - shut down the clock
283 */
284static void
285acts_shutdown(
286	int	unit,
287	struct peer *peer
288	)
289{
290	struct actsunit *up;
291	struct refclockproc *pp;
292
293	/*
294	 * Warning: do this only when a call is not in progress.
295	 */
296	pp = peer->procptr;
297	up = pp->unitptr;
298	acts_close(peer);
299	free(up);
300}
301
302
303/*
304 * acts_receive - receive data from the serial interface
305 */
306static void
307acts_receive(
308	struct recvbuf *rbufp
309	)
310{
311	struct actsunit *up;
312	struct refclockproc *pp;
313	struct peer *peer;
314	char	tbuf[sizeof(up->buf)];
315	char *	tptr;
316	int	octets;
317
318	/*
319	 * Initialize pointers and read the timecode and timestamp. Note
320	 * we are in raw mode and victim of whatever the terminal
321	 * interface kicks up; so, we have to reassemble messages from
322	 * arbitrary fragments. Capture the timecode at the beginning of
323	 * the message and at the '*' and '#' on-time characters.
324	 */
325	peer = rbufp->recv_peer;
326	pp = peer->procptr;
327	up = pp->unitptr;
328	octets = sizeof(up->buf) - (up->bufptr - up->buf);
329	refclock_gtraw(rbufp, tbuf, octets, &pp->lastrec);
330	for (tptr = tbuf; *tptr != '\0'; tptr++) {
331		if (*tptr == LF) {
332			if (up->bufptr == up->buf) {
333				up->tstamp = pp->lastrec;
334				continue;
335			} else {
336				*up->bufptr = '\0';
337				up->bufptr = up->buf;
338				acts_message(peer, up->buf);
339			}
340		} else if (!iscntrl((unsigned char)*tptr)) {
341			*up->bufptr++ = *tptr;
342			if (*tptr == '*' || *tptr == '#') {
343				up->tstamp = pp->lastrec;
344				refclock_write(peer, tptr, 1, "data");
345			}
346		}
347	}
348}
349
350
351/*
352 * acts_message - process message
353 */
354void
355acts_message(
356	struct peer *peer,
357	const char *msg
358	)
359{
360	struct actsunit *up;
361	struct refclockproc *pp;
362	char	tbuf[BMAX];
363	int		dtr = TIOCM_DTR;
364
365	DPRINTF(1, ("acts: %d %s\n", (int)strlen(msg), msg));
366
367	/*
368	 * What to do depends on the state and the first token in the
369	 * message.
370	 */
371	pp = peer->procptr;
372	up = pp->unitptr;
373
374	/*
375	 * Extract the first token in the line.
376	 */
377	strlcpy(tbuf, msg, sizeof(tbuf));
378	strtok(tbuf, " ");
379	switch (up->state) {
380
381	/*
382	 * We are waiting for the OK response to the modem setup
383	 * command. When this happens, dial the number followed.
384	 * If anything other than OK is received, just ignore it
385	 * and wait for timeoue.
386	 */
387	case S_SETUP:
388		if (strcmp(tbuf, "OK") != 0) {
389			/*
390			 * We disable echo with MODEM_SETUP's E0 but
391			 * if the modem was previously E1, we will
392			 * see MODEM_SETUP echoed before the OK/ERROR.
393			 * Ignore it.
394			 */
395			if (!strcmp(tbuf, modem_setup))
396				return;
397			break;
398		}
399
400		mprintf_event(PEVNT_CLOCK, peer, "DIAL #%d %s",
401			      up->retry, sys_phone[up->retry]);
402		if (ioctl(pp->io.fd, TIOCMBIS, &dtr) < 0)
403			msyslog(LOG_ERR, "acts: ioctl(TIOCMBIS) failed: %m");
404		refclock_write(peer, sys_phone[up->retry],
405			       strlen(sys_phone[up->retry]),
406			       "DIAL");
407		refclock_write(peer, "\r", 1, "CR");
408		up->retry++;
409		up->state = S_CONNECT;
410		up->timer = ANSWER;
411		return;
412
413	/*
414	 * We are waiting for the CONNECT response to the dial
415	 * command. When this happens, listen for timecodes. If
416	 * somthing other than CONNECT is received, like BUSY
417	 * or NO CARRIER, abort the call.
418	 */
419	case S_CONNECT:
420		if (strcmp(tbuf, "CONNECT") != 0)
421			break;
422
423		report_event(PEVNT_CLOCK, peer, msg);
424		up->state = S_MSG;
425		up->timer = TIMECODE;
426		return;
427
428	/*
429	 * We are waiting for a timecode response. Pass it to
430	 * the parser. If NO CARRIER is received, save the
431	 * messages and abort the call.
432	 */
433	case S_MSG:
434		if (strcmp(tbuf, "NO") == 0)
435			report_event(PEVNT_CLOCK, peer, msg);
436		if (up->msgcnt < MAXCODE)
437			acts_timecode(peer, msg);
438		else
439			acts_timeout(peer, S_MSG);
440		return;
441	}
442
443	/*
444	 * Other response. Tell us about it.
445	 */
446	report_event(PEVNT_CLOCK, peer, msg);
447	acts_close(peer);
448}
449
450
451/*
452 * acts_timeout - called on timeout
453 */
454static void
455acts_timeout(
456	struct peer *peer,
457	teModemState	dstate
458	)
459{
460	struct actsunit *up;
461	struct refclockproc *pp;
462	int	fd;
463	char	device[20];
464	char	lockfile[128], pidbuf[8];
465
466	/*
467	 * The state machine is driven by messages from the modem,
468	 * when first started and at timeout.
469	 */
470	pp = peer->procptr;
471	up = pp->unitptr;
472	switch (dstate) {
473
474	/*
475	 * System poll event. Lock the modem port, open the device
476	 * and send the setup command.
477	 */
478	case S_IDLE:
479		if (-1 != pp->io.fd)
480			return;		/* port is already open */
481
482		/*
483		 * Lock the modem port. If busy, retry later. Note: if
484		 * something fails between here and the close, the lock
485		 * file may not be removed.
486		 */
487		if (pp->sloppyclockflag & CLK_FLAG2) {
488			snprintf(lockfile, sizeof(lockfile), LOCKFILE,
489			    up->unit);
490			fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL,
491			    0644);
492			if (fd < 0) {
493				report_event(PEVNT_CLOCK, peer, "acts: port busy");
494				return;
495			}
496			snprintf(pidbuf, sizeof(pidbuf), "%d\n",
497			    (u_int)getpid());
498			if (write(fd, pidbuf, strlen(pidbuf)) < 0)
499				msyslog(LOG_ERR, "acts: write lock fails %m");
500			close(fd);
501		}
502
503		/*
504		 * Open the device in raw mode and link the I/O.
505		 */
506		snprintf(device, sizeof(device), DEVICE,
507		    up->unit);
508		fd = refclock_open(&peer->srcadr, device, SPEED232, LDISC_ACTS |
509		    LDISC_RAW | LDISC_REMOTE);
510		if (fd < 0) {
511			msyslog(LOG_ERR, "acts: open fails %m");
512			return;
513		}
514		pp->io.fd = fd;
515		if (!io_addclock(&pp->io)) {
516			msyslog(LOG_ERR, "acts: addclock fails");
517			close(fd);
518			pp->io.fd = -1;
519			return;
520		}
521		up->msgcnt = 0;
522		up->bufptr = up->buf;
523
524		/*
525		 * If the port is directly connected to the device, skip
526		 * the modem business and send 'T' for Spectrabum.
527		 */
528		if (sys_phone[up->retry] == NULL) {
529			refclock_write(peer, "T", 1, "T");
530			up->state = S_MSG;
531			up->timer = TIMECODE;
532			return;
533		}
534
535		/*
536		 * Initialize the modem. This works with Hayes-
537		 * compatible modems.
538		 */
539		mprintf_event(PEVNT_CLOCK, peer, "SETUP %s",
540			      modem_setup);
541		refclock_write(peer, modem_setup, strlen(modem_setup),
542			       "SETUP");
543		refclock_write(peer, "\r", 1, "CR");
544		up->state = S_SETUP;
545		up->timer = SETUP;
546		return;
547
548	/*
549	 * In SETUP state the modem did not respond OK to setup string.
550	 */
551	case S_SETUP:
552		report_event(PEVNT_CLOCK, peer, "no modem");
553		break;
554
555	/*
556	 * In CONNECT state the call did not complete. Abort the call.
557	 */
558	case S_CONNECT:
559		report_event(PEVNT_CLOCK, peer, "no answer");
560		break;
561
562	/*
563	 * In MSG states no further timecodes are expected. If any
564	 * timecodes have arrived, update the clock. In any case,
565	 * terminate the call.
566	 */
567	case S_MSG:
568		if (up->msgcnt == 0) {
569			report_event(PEVNT_CLOCK, peer, "no timecodes");
570		} else {
571			pp->lastref = pp->lastrec;
572			record_clock_stats(&peer->srcadr, pp->a_lastcode);
573			refclock_receive(peer);
574		}
575		break;
576	}
577	acts_close(peer);
578}
579
580
581/*
582 * acts_close - close and prepare for next call.
583 *
584 * In ClOSE state no further protocol actions are required
585 * other than to close and release the device and prepare to
586 * dial the next number if necessary.
587 */
588void
589acts_close(
590	struct peer *peer
591	)
592{
593	struct actsunit *up;
594	struct refclockproc *pp;
595	char	lockfile[128];
596	int	dtr;
597
598	pp = peer->procptr;
599	up = pp->unitptr;
600	if (pp->io.fd != -1) {
601		report_event(PEVNT_CLOCK, peer, "close");
602		dtr = TIOCM_DTR;
603		if (ioctl(pp->io.fd, TIOCMBIC, &dtr) < 0)
604			msyslog(LOG_ERR, "acts: ioctl(TIOCMBIC) failed: %m");
605		io_closeclock(&pp->io);
606		pp->io.fd = -1;
607	}
608	if (pp->sloppyclockflag & CLK_FLAG2) {
609		snprintf(lockfile, sizeof(lockfile),
610		    LOCKFILE, up->unit);
611		unlink(lockfile);
612	}
613	if (up->msgcnt == 0 && up->retry > 0) {
614		if (sys_phone[up->retry] != NULL) {
615			up->state = S_IDLE;
616			up->timer = REDIAL;
617			return;
618		}
619	}
620	up->state = S_IDLE;
621	up->timer = 0;
622}
623
624
625/*
626 * acts_poll - called by the transmit routine
627 */
628static void
629acts_poll(
630	int	unit,
631	struct peer *peer
632	)
633{
634	struct actsunit *up;
635	struct refclockproc *pp;
636
637	/*
638	 * This routine is called at every system poll. All it does is
639	 * set flag1 under certain conditions. The real work is done by
640	 * the timeout routine and state machine.
641	 */
642	pp = peer->procptr;
643	up = pp->unitptr;
644	switch (peer->ttl) {
645
646	/*
647	 * In manual mode the calling program is activated by the ntpdc
648	 * program using the enable flag (fudge flag1), either manually
649	 * or by a cron job.
650	 */
651	case MODE_MANUAL:
652		return;
653
654	/*
655	 * In automatic mode the calling program runs continuously at
656	 * intervals determined by the poll event or specified timeout.
657	 */
658	case MODE_AUTO:
659		break;
660
661	/*
662	 * In backup mode the calling program runs continuously as long
663	 * as either no peers are available or this peer is selected.
664	 */
665	case MODE_BACKUP:
666		if (!(sys_peer == NULL || sys_peer == peer))
667			return;
668
669		break;
670	}
671	pp->polls++;
672	if (S_IDLE == up->state) {
673		up->retry = 0;
674		acts_timeout(peer, S_IDLE);
675	}
676}
677
678
679/*
680 * acts_timer - called at one-second intervals
681 */
682static void
683acts_timer(
684	int	unit,
685	struct peer *peer
686	)
687{
688	struct actsunit *up;
689	struct refclockproc *pp;
690
691	/*
692	 * This routine implments a timeout which runs for a programmed
693	 * interval. The counter is initialized by the state machine and
694	 * counts down to zero. Upon reaching zero, the state machine is
695	 * called. If flag1 is set while timer is zero, force a call.
696	 */
697	pp = peer->procptr;
698	up = pp->unitptr;
699	if (up->timer == 0) {
700		if (pp->sloppyclockflag & CLK_FLAG1) {
701			pp->sloppyclockflag &= ~CLK_FLAG1;
702			acts_timeout(peer, S_IDLE);
703		}
704	} else {
705		up->timer--;
706		if (up->timer == 0)
707			acts_timeout(peer, up->state);
708	}
709}
710
711/*
712 * acts_timecode - identify the service and parse the timecode message
713 */
714void
715acts_timecode(
716	struct peer *	peer,	/* peer structure pointer */
717	const char *	str	/* timecode string */
718	)
719{
720	struct actsunit *up;
721	struct refclockproc *pp;
722	int	day;		/* day of the month */
723	int	month;		/* month of the year */
724	u_long	mjd;		/* Modified Julian Day */
725	double	dut1;		/* DUT adjustment */
726
727	u_int	dst;		/* ACTS daylight/standard time */
728	u_int	leap;		/* ACTS leap indicator */
729	double	msADV;		/* ACTS transmit advance (ms) */
730	char	utc[10];	/* ACTS timescale */
731	char	flag;		/* ACTS on-time character (* or #) */
732
733	char	synchar;	/* WWVB synchronized indicator */
734	char	qualchar;	/* WWVB quality indicator */
735	char	leapchar;	/* WWVB leap indicator */
736	char	dstchar;	/* WWVB daylight/savings indicator */
737	int	tz;		/* WWVB timezone */
738
739	int	leapmonth;	/* PTB/NPL month of leap */
740	char	leapdir;	/* PTB/NPL leap direction */
741
742	/*
743	 * The parser selects the modem format based on the message
744	 * length. Since the data are checked carefully, occasional
745	 * errors due noise are forgivable.
746	 */
747	pp = peer->procptr;
748	up = pp->unitptr;
749	pp->nsec = 0;
750	switch (strlen(str)) {
751
752	/*
753	 * For USNO format on-time character '*', which is on a line by
754	 * itself. Be sure a timecode has been received.
755	 */
756	case 1:
757		if (*str == '*' && up->msgcnt > 0)
758			break;
759
760		return;
761
762	/*
763	 * ACTS format A: "jjjjj yy-mm-dd hh:mm:ss ds l uuu aaaaa
764	 * UTC(NIST) *".
765	 */
766	case LENACTS:
767		if (sscanf(str,
768		    "%5ld %2d-%2d-%2d %2d:%2d:%2d %2d %1d %3lf %5lf %9s %c",
769		    &mjd, &pp->year, &month, &day, &pp->hour,
770		    &pp->minute, &pp->second, &dst, &leap, &dut1,
771		    &msADV, utc, &flag) != 13) {
772			refclock_report(peer, CEVNT_BADREPLY);
773			return;
774		}
775		pp->day = ymd2yd(pp->year, month, day);
776		pp->leap = LEAP_NOWARNING;
777		if (leap == 1)
778			pp->leap = LEAP_ADDSECOND;
779		else if (leap == 2)
780			pp->leap = LEAP_DELSECOND;
781		memcpy(&pp->refid, REFACTS, 4);
782		up->msgcnt++;
783		if (flag != '#' && up->msgcnt < 10)
784			return;
785
786		break;
787
788	/*
789	 * USNO format: "jjjjj nnn hhmmss UTC"
790	 */
791	case LENUSNO:
792		if (sscanf(str, "%5ld %3d %2d%2d%2d %3s",
793		    &mjd, &pp->day, &pp->hour, &pp->minute,
794		    &pp->second, utc) != 6) {
795			refclock_report(peer, CEVNT_BADREPLY);
796			return;
797		}
798
799		/*
800		 * Wait for the on-time character, which follows in a
801		 * separate message. There is no provision for leap
802		 * warning.
803		 */
804		pp->leap = LEAP_NOWARNING;
805		memcpy(&pp->refid, REFUSNO, 4);
806		up->msgcnt++;
807		break;
808
809	/*
810	 * PTB/NPL format: "yyyy-mm-dd hh:mm:ss MEZ"
811	 */
812	case LENPTB:
813		if (sscanf(str,
814		    "%*4d-%*2d-%*2d %*2d:%*2d:%2d %*5c%*12c%4d%2d%2d%2d%2d%5ld%2lf%c%2d%3lf%*15c%c",
815		    &pp->second, &pp->year, &month, &day, &pp->hour,
816		    &pp->minute, &mjd, &dut1, &leapdir, &leapmonth,
817		    &msADV, &flag) != 12) {
818			refclock_report(peer, CEVNT_BADREPLY);
819			return;
820		}
821		pp->leap = LEAP_NOWARNING;
822		if (leapmonth == month) {
823			if (leapdir == '+')
824				pp->leap = LEAP_ADDSECOND;
825			else if (leapdir == '-')
826				pp->leap = LEAP_DELSECOND;
827		}
828		pp->day = ymd2yd(pp->year, month, day);
829		memcpy(&pp->refid, REFPTB, 4);
830		up->msgcnt++;
831		break;
832
833
834	/*
835	 * WWVB format 0: "I  ddd hh:mm:ss DTZ=nn"
836	 */
837	case LENWWVB0:
838		if (sscanf(str, "%c %3d %2d:%2d:%2d %cTZ=%2d",
839		    &synchar, &pp->day, &pp->hour, &pp->minute,
840		    &pp->second, &dstchar, &tz) != 7) {
841			refclock_report(peer, CEVNT_BADREPLY);
842			return;
843		}
844		pp->leap = LEAP_NOWARNING;
845		if (synchar != ' ')
846			pp->leap = LEAP_NOTINSYNC;
847		memcpy(&pp->refid, REFWWVB, 4);
848		up->msgcnt++;
849		break;
850
851	/*
852	 * WWVB format 2: "IQyy ddd hh:mm:ss.mmm LD"
853	 */
854	case LENWWVB2:
855		if (sscanf(str, "%c%c%2d %3d %2d:%2d:%2d.%3ld%c%c%c",
856		    &synchar, &qualchar, &pp->year, &pp->day,
857		    &pp->hour, &pp->minute, &pp->second, &pp->nsec,
858		    &dstchar, &leapchar, &dstchar) != 11) {
859			refclock_report(peer, CEVNT_BADREPLY);
860			return;
861		}
862		pp->nsec *= 1000000;
863		pp->leap = LEAP_NOWARNING;
864		if (synchar != ' ')
865			pp->leap = LEAP_NOTINSYNC;
866		else if (leapchar == 'L')
867			pp->leap = LEAP_ADDSECOND;
868		memcpy(&pp->refid, REFWWVB, 4);
869		up->msgcnt++;
870		break;
871
872	/*
873	 * None of the above. Just forget about it and wait for the next
874	 * message or timeout.
875	 */
876	default:
877		return;
878	}
879
880	/*
881	 * We have a valid timecode. The fudge time1 value is added to
882	 * each sample by the main line routines. Note that in current
883	 * telephone networks the propatation time can be different for
884	 * each call and can reach 200 ms for some calls.
885	 */
886	peer->refid = pp->refid;
887	pp->lastrec = up->tstamp;
888	if (up->msgcnt == 0)
889		return;
890
891	strlcpy(pp->a_lastcode, str, sizeof(pp->a_lastcode));
892	pp->lencode = strlen(pp->a_lastcode);
893	if (!refclock_process(pp)) {
894		refclock_report(peer, CEVNT_BADTIME);
895		return;
896	}
897	pp->lastref = pp->lastrec;
898}
899#else
900NONEMPTY_TRANSLATION_UNIT
901#endif /* REFCLOCK */
902