These patches enable the PTBACTS reference clock driver to also work with the service provided by the NPL in the UK. This has been tested with a few polls, but not extensively, as this is a premium rate service and my long term aim is to use a radio reference. It also replaces the ad hoc tests for modem type services in several places, which didn't consistently list all such clocks, by a test for a telephone type service as would be encoded into protocol responses. This breaks the structuring a bit, as, although the data structures allow for this information to be used globally, the actual definitions are only held where they are used for the protocol control messages. This has not been extensively tested. Finally I've updated the documentation to some extent. It appears already to have been incorrect, and I haven't necessarily fully corrected it. Note that one of the comments says the code breaks in 2000; this is not true, because 2000 is divisible by 400 and therefore excluded from the 100 year exceptions to leap years. I've corrected the comments. As I can find no obvious fault with the handling of PTBACTS by Linux (1.2.13 a.out), I've added this to the makefile rules for Linux. *** html/driver23.html.3.5f Tue Mar 19 02:45:46 1996 --- html/driver23.html Sun Jul 7 23:07:40 1996 *************** *** 1,7 ****
/dev/ptbu
; 1200 baud, 8-bits,
no parity
! No further information available.
/dev/ptbu
; 1200 baud, 8-bits,
no parity
! tty_clk
This is a variation of the NIST driver ! which supports the German PTB and British NPL TRUETIME modem time ! services. ! !
Both services use the same basic format. The German format is ! described below. The official specification for the British format can ! be found in the National Physical Laboratory's TRUETIME web ! page. The main difference is that PTB use timezones MEZ (i.e. ! +0100) and MESZ (+0200), whereas NPL use UTC+0 and UTC+1. ! !
! 00000000001111111111222222222233333333334444444444555555555566 ! 01234567890123456789012345678901234567890123456789012345678901 ! 1995-01-23 20:58:51 MEZ 10402303260219950123195849740+4000050 ! A B C D EF G H IJ K L M N O P Q R S T U V W ! ! 66666666777777777 7 ! 23456789012345678 9 ! 0 * ! XY Z<CR><LF> !! !
Where: !
The PTB timecode service is run by the Physikalisch-Technische ! Bundesanstalt can be accessed on +49 531 512038. The NPL TRUETIME ! service is run by the National Physical Laboratory and can be ! contacted on the UK number 0891 516 333. This is a premium rate number ! and may not be internationally accessible; if it is, the code will ! be +44 891 516 333. The NPL service is not documented as supporting ! the echo check method for round trip delays.
time2 time
! stratum number
time2 time
! stratum number
refid string
USNO
.
flag1 0 | 1
! flag2 0 | 1
! flag3 0 | 1
refid string
PTBT
.
flag1 0 | 1
! flag2 0 | 1
! flag3 0 | 1
This driver supports the NIST Automated Computer Time Service (ACTS). + A variation also supports the + German PTB and British NPL services. It periodically dials a prespecified telephone number, receives the NIST timecode data and calculates the local clock correction. It designed primarily for use when neither a radio clock nor connectivity to *************** *** 64,79 **** that don't, fudge flag2 should be set to disable the feature. In this case the fudge time1 parameter represents the total propagation delay due to all causes and must be determined by external calibration. -
The ACTS call interval is determined by a counter initially set to - the fudge time2 parameter. At each poll interval, minpoll (usually 64 s) - is subtracted from the counter. When the counter is equal to or less - than zero, the fudge flag1 is set, which causes up to three call - attempts to be made to ACTS. The fudge flag1 is reset after a valid - clock update has been determined or by a device fault, timeout or - manually using xntpdc. After a valid clock update, the counter is reset - for the next interval. Setting the fudge time2 parameter to zero - disables automatic call attempts. Manual call attempts can be made at - any time by setting fudge flag1 using xntpdc.
The NIST timecode message is transmitted at 1200 bps in the following format: --- 67,72 ---- *************** *** 93,98 **** --- 86,92 ---- +
The timecode message is transmitted continuously after a signon banner, which this driver ignores. The driver also ignores all but the yy-mm-dd, hh:mm:ss and on-time character '*' fields, although it checks *************** *** 122,133 **** --- 116,134 ---- command, in which case only this driver will be selected for synchronization and all other discipline sources will be ignored. +
The original documentation contained the following statement, + however I can find no evidence that the clock filter is ever bypassed + by this driver: + +
+Unlike other drivers, each ACTS call generates one clock correction and that correction is processed immediately. There is no wait to allow the clock filter to accumulate samples. In addition, the watchdog timeout of the local clock algorithm is disabled, so that a correction received from this driver that exceeds CLOCK_MAX (128 ms) causes an immediate step/slew. +
Since the interval between updates can be much longer than used with ordinary NTP peers, the local clock procedure has been modified to operate in either of two modes, depending on whether the interval *************** *** 143,159 ****
Since ACTS will be a toll call in most areas of the country, it is necessary to carefully manage the call frequency. This can be done in two ways, by specifying the interval between calls, or by setting a flag ! bit manually or via a cron job. The call interval is determined by a ! counter initially set to the fudge time2 parameter. At each poll ! interval, minpoll (usually 64 s) is subtracted from the counter. When ! the counter is equal to or less than zero, the fudge flag1 is set, which causes up to three call attempts to be made. The fudge flag1 is reset after ten offset samples have been determined in a single call or by a device fault, timeout or manually using xntpdc. Upon successful completion of a call, the eight samples have been shifted into the clock filter, the local clock updated and the counter reset for the next ! interval. Setting the fudge time2 parameter to zero disables automatic ! call attempts.
Manual call attempts can be made at any time by setting fudge flag1 using xntpdc. For example, the xntpdc command --- 144,159 ----
Since ACTS will be a toll call in most areas of the country, it is necessary to carefully manage the call frequency. This can be done in two ways, by specifying the interval between calls, or by setting a flag ! bit manually or via a cron job. The call interval is determined by ! the fudge time2 parameter. This approximates ! the allowable measurement error and, in conjunction with the measured ! error determines when the fudge flag1 is automatically set. When set this causes up to three call attempts to be made. The fudge flag1 is reset after ten offset samples have been determined in a single call or by a device fault, timeout or manually using xntpdc. Upon successful completion of a call, the eight samples have been shifted into the clock filter, the local clock updated and the counter reset for the next ! interval.
Manual call attempts can be made at any time by setting fudge flag1 using xntpdc. For example, the xntpdc command *************** *** 182,188 ****
! /usr/local/bin/xntpdc--- 182,188 ---- ! /usr/local/bin/xntpdc <file*************** *** 198,205 ****Specifies the time offset calibration factor, in seconds and fraction, with default 0.0. ! time2 time
!Not used by this driver. stratum number
Specifies the driver stratum, in decimal from 0 to 15, with default --- 198,217 ---- Specifies the time offset calibration factor, in seconds and fraction, with default 0.0. ! time2 time
!In automatic and backup modes, the driver determines the call ! interval using a procedure depending on the measured prediction ! error and the fudge time2 parameter. If the error exceeds time2 for a ! number of times depending on the current interval, the interval is ! decreased, but not less than about 1000 s. If the error is less than ! time2 for some number of times, the interval is increased, but not ! more than about 18 h. With the default value of zero for fudge time2, ! the interval will increase from 1000 s to the 4000-8000-s range, in ! which the expected accuracy should be in the 1-2-ms range. Setting ! fudge time2 to a large value, like 0.1 s, may result in errors of ! that order, but increase the call interval to the maximum. The exact ! value for each configuration will depend on the modem and operating ! system involved, so some experimentation may be necessary. stratum number
Specifies the driver stratum, in decimal from 0 to 15, with default *************** *** 210,219 **** to four characters, with default ACTS
.flag1 0 | 1
!Not used by this driver. flag2 0 | 1
!Not used by this driver. flag3 0 | 1
Not used by this driver. --- 222,232 ---- to four characters, with default ACTS
.flag1 0 | 1
!Setting this forces a call at the next poll interval and resetting ! it suppresses a pending call. flag2 0 | 1
!Turns off echo delay measurement. flag3 0 | 1
Not used by this driver. *** xntpd/refclock_acts.c.3.5f Mon May 27 19:03:23 1996 --- xntpd/refclock_acts.c Sun Jul 7 22:59:11 1996 *************** *** 16,21 **** --- 16,22 ---- #include "ntp_unixtime.h" #include "ntp_refclock.h" #include "ntp_stdlib.h" + #include "ntp_control.h" /* * This driver supports the NIST Automated Computer Time Service (ACTS). *************** *** 264,269 **** --- 265,277 ---- * Z on time marker (* - assumed delay / # measured delay) * ! ! is second change ! * + * This format is also used by the National Physical Laboratory (NPL)'s + * TRUETIME service in the UK. In this case the timezone field is + * UTC+0 or UTC+1 for standard and daylight saving time. The phone + * number for this service (a premium rate number) is 0891 516 333. + * It is not clear whether the echo check is implemented. + * + * For more detail, see http://www.npl.co.uk/npl/cetm/taf/truetime.html. */ /* *************** *** 449,454 **** --- 457,463 ---- memcpy((char *)&pp->refid, REFID, 4); peer->minpoll = ACTS_MINPOLL; peer->maxpoll = ACTS_MAXPOLL; + peer->sstclktype = CTL_SST_TS_TELEPHONE; /* * Initialize modem and kill DTR. We skedaddle if this comes *************** *** 646,652 **** * 1995-01-23 20:58:51 MEZ 10402303260219950123195849740+40000500 * */ if (sscanf(pp->lastcode, ! "%*4d-%*2d-%*2d %*2d:%*2d:%2d %*4c %*12c%4d%2d%2d%2d%2d%5ld%2lf%c%2d%3lf%*15c%c", &pp->second, &pp->year, &month, &day, &pp->hour, &pp->minute, &mjd, &dut1, &leapdir, &leapmonth, &msADV, &flag) != 12) { refclock_report(peer, CEVNT_BADREPLY); return; --- 655,661 ---- * 1995-01-23 20:58:51 MEZ 10402303260219950123195849740+40000500 * */ if (sscanf(pp->lastcode, ! "%*4d-%*2d-%*2d %*2d:%*2d:%2d %*5c%*12c%4d%2d%2d%2d%2d%5ld%2lf%c%2d%3lf%*15c%c", &pp->second, &pp->year, &month, &day, &pp->hour, &pp->minute, &mjd, &dut1, &leapdir, &leapmonth, &msADV, &flag) != 12) { refclock_report(peer, CEVNT_BADREPLY); return; *************** *** 663,672 **** (void)write(pp->io.fd, &flag, 1); /* ! * Yes, I know this code incorrectly thinks that 2100 is a leap ! * year. The ACTS timecode format croaks long before then anyway. ! * Life is short. Would only the timecode mavens resist the urge ! * to express months of the year and days of the month in favor of * days of the year. */ if (month < 1 || month > 12 || day < 1) { --- 672,681 ---- (void)write(pp->io.fd, &flag, 1); /* ! * Yes, I know this code incorrectly thinks that 2000 is a leap ! * year. The ACTS timecode format croaks then anyway. Life is ! * short. Would only the timecode mavens resist the urge to ! * express months of the year and days of the month in favor of * days of the year. */ if (month < 1 || month > 12 || day < 1) { *************** *** 849,856 **** "clock %s ACTS backup started ", ntoa(&peer->srcadr)); } ! } else if (up->run && sys_peer->refclktype != ! REFCLK_NIST_ACTS) { peer->hpoll = peer->minpoll; up->run = 0; NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */ --- 858,864 ---- "clock %s ACTS backup started ", ntoa(&peer->srcadr)); } ! } else if (up->run && sys_peer->sstclktype != CTL_SST_TS_TELEPHONE) { peer->hpoll = peer->minpoll; up->run = 0; NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */ *** xntpd/ntp_unixclock.c.3.5f Mon Apr 15 21:36:07 1996 --- xntpd/ntp_unixclock.c Sat May 18 20:23:42 1996 *************** *** 682,688 **** #endif __adjtimex(&txc); ! *tickadj = (u_long)1; /* our adjtime is accurate */ *tick = (u_long)txc.tick; } #endif /* SYS_LINUX */ --- 682,688 ---- #endif __adjtimex(&txc); ! *tickadj = (u_long)5; /* This is good for 1.2.13 kernel */ *tick = (u_long)txc.tick; } #endif /* SYS_LINUX */ *** xntpd/ntp_proto.c.3.5f Tue Feb 20 04:30:04 1996 --- xntpd/ntp_proto.c Sun Jul 7 23:32:25 1996 *************** *** 10,15 **** --- 10,16 ---- #include "ntpd.h" #include "ntp_stdlib.h" #include "ntp_unixtime.h" + #include "ntp_control.h" #if defined(VMS) && defined(VMS_LOCALUNIT) /*wjm*/ #include "ntp_refclock.h" *************** *** 1664,1670 **** if (!(peer->flags & FLAG_PREFER)) continue; /* no local clock */ } ! if (peer->refclktype == REFCLK_NIST_ACTS) { typeacts = peer; if (!(peer->flags & FLAG_PREFER)) continue; /* no acts */ --- 1665,1671 ---- if (!(peer->flags & FLAG_PREFER)) continue; /* no local clock */ } ! if (peer->sstclktype == CTL_SST_TS_TELEPHONE) { typeacts = peer; if (!(peer->flags & FLAG_PREFER)) continue; /* no acts */ *************** *** 1921,1928 **** /* * Mitigation rules of the game. There are several types of * peers that make a difference here: (1) prefer local peers ! * (type REFCLK_LOCALCLOCK with FLAG_PREFER) or prefer acts ! * peers (type REFCLK_NIST_ATOM with FLAG_PREFER), (2) pps peers * (type REFCLK_ATOM_PPS), (3) remaining prefer peers (flag * FLAG_PREFER), (4) the existing system peer, if any, (5) the * head of the survivor list. Note that only one peer can be --- 1922,1929 ---- /* * Mitigation rules of the game. There are several types of * peers that make a difference here: (1) prefer local peers ! * (type REFCLK_LOCALCLOCK with FLAG_PREFER) or prefer modem ! * peers (type REFCLK_NIST_ATOM etc with FLAG_PREFER), (2) pps peers * (type REFCLK_ATOM_PPS), (3) remaining prefer peers (flag * FLAG_PREFER), (4) the existing system peer, if any, (5) the * head of the survivor list. Note that only one peer can be *************** *** 1932,1938 **** */ osys_peer = sys_peer; if (typeprefer && (typeprefer->refclktype == REFCLK_LOCALCLOCK || ! typeprefer->refclktype == REFCLK_NIST_ACTS || !typepps)) { sys_peer = typeprefer; sys_peer->selectdisp = 0; sys_offset = sys_peer->offset; --- 1933,1939 ---- */ osys_peer = sys_peer; if (typeprefer && (typeprefer->refclktype == REFCLK_LOCALCLOCK || ! typeprefer->sstclktype == CTL_SST_TS_TELEPHONE || !typepps)) { sys_peer = typeprefer; sys_peer->selectdisp = 0; sys_offset = sys_peer->offset; *** xntpd/refclock_usno.c.3.5f Sun Jun 18 13:30:26 1995 --- xntpd/refclock_usno.c Mon Jul 22 20:54:03 1996 *************** *** 13,18 **** --- 13,19 ---- #include "ntp_unixtime.h" #include "ntp_refclock.h" #include "ntp_stdlib.h" + #include "ntp_control.h" /* * This driver supports the Naval Observatory dialup at +1 202 653 0351. *************** *** 158,163 **** --- 159,165 ---- memcpy((char *)&pp->refid, REFID, 4); peer->minpoll = USNO_MINPOLL; peer->maxpoll = USNO_MAXPOLL; + peer->sstclktype = CTL_SST_TS_TELEPHONE; /* * Allocate and initialize unit structure *************** *** 492,499 **** "clock %s USNO backup started ", ntoa(&peer->srcadr)); } ! } else if (up->run && sys_peer->refclktype != ! REFCLK_NIST_ACTS && sys_peer->refclktype != REFCLK_USNO) { peer->hpoll = peer->minpoll; up->run = 0; NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */ --- 494,500 ---- "clock %s USNO backup started ", ntoa(&peer->srcadr)); } ! } else if (up->run && sys_peer->sstclktype != CTL_SST_TS_TELEPHONE) { peer->hpoll = peer->minpoll; up->run = 0; NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */