+2000-09-16 Harlan Stenn <stenn@whimsy.udel.edu>
+
+ * ntptrace/ntptrace.c:
+ * ntpdate/ntptimeset.c (receive):
+ * ntpdate/ntpdate.c (receive):
+ STRATUM cleanup
+ * ntpd/refclock_atom.c (atom_poll): Autostratum. Lose the leap.
+ * ntpd/ntp_proto.c: sys_prefer
+ (process_packet): stratum cleanup
+ (clock_select): Autostratum the ATOM
+ * ntpd/ntp_loopfilter.c: pps_update/pps_stratum wiggle.
+ * include/ntpd.h: Lose pps_update, gain sys_prefer
+ * include/ntp.h: STRATUM variable cleanup
+ From Dave Mills
+
2000-09-13 Harlan Stenn <stenn@whimsy.udel.edu>
* ntpd/refclock_oncore.c (oncore_get_timestamp): Prind debug
#define NTP_VERSION ((u_char)4) /* current version number */
#define NTP_OLDVERSION ((u_char)1) /* oldest credible version */
#define NTP_PORT 123 /* included for sake of non-unix machines */
-#define NTP_MAXSTRATUM ((u_char)15) /* max stratum, infinity a la Bellman-Ford */
#define NTP_MAXAGE 86400 /* one day in seconds */
#define NTP_UNREACH 16 /* poll interval backoff count */
#define NTP_TAILMAX 4 /* tailgate poll counter max */
* Values for peer.stratum, sys_stratum
*/
#define STRATUM_REFCLOCK ((u_char)0) /* stratum claimed by primary clock */
-#define STRATUM_PRIMARY ((u_char)1) /* host has a primary clock */
-#define STRATUM_INFIN ((u_char)NTP_MAXSTRATUM) /* infinity a la Bellman-Ford */
/* A stratum of 0 in the packet is mapped to 16 internally */
#define STRATUM_PKT_UNSPEC ((u_char)0) /* unspecified in packet */
-#define STRATUM_UNSPEC ((u_char)(NTP_MAXSTRATUM+(u_char)1)) /* unspecified */
+#define STRATUM_UNSPEC ((u_char)16) /* unspecified */
/*
* Values for peer.flags
extern int pll_control; /* kernel support available */
extern int kern_enable; /* kernel support enabled */
extern int ext_enable; /* external clock enabled */
-extern int pps_update; /* pps update valid */
extern int allow_set_backward; /* step corrections allowed */
extern int correct_any; /* corrections > 1000 s allowed */
extern u_int32 sys_refid; /* reference source for local clock */
extern l_fp sys_reftime; /* time we were last updated */
extern struct peer *sys_peer; /* our current peer */
+extern struct peer *sys_prefer; /* our cherished peer */
extern u_long sys_automax; /* maximum session key lifetime */
/*
* support is used as described above; if false, the kernel is bypassed
* entirely and the daemon PLL used instead.
*
- * Each update to a prefer peer sets pps_update if it survives the
+ * Each update to a prefer peer sets pps_stratum if it survives the
* intersection algorithm and its time is within range. The PPS time
* discipline is enabled (STA_PPSTIME bit set in the status word) when
- * pps_update is true and the PPS frequency discipline is enabled. If
+ * pps_stratum is true and the PPS frequency discipline is enabled. If
* the PPS time discipline is enabled and the kernel reports a PPS
* signal is present, the pps_control variable is set to the current
* time. If the current time is later than pps_control by PPS_MAXAGE
int pll_control; /* kernel support available */
int kern_enable; /* kernel support enabled */
int ext_enable; /* external clock enabled */
-int pps_update; /* pps update valid */
+int pps_stratum; /* pps stratum */
int allow_set_backward = TRUE; /* step corrections allowed */
int correct_any = FALSE; /* corrections > 1000 s allowed */
*/
if (pll_status & STA_PPSSIGNAL)
ntv.status |= STA_PPSFREQ;
- if (pll_status & STA_PPSFREQ && pps_update)
+ if (pll_status & STA_PPSFREQ && pps_stratum < STRATUM_UNSPEC)
ntv.status |= STA_PPSTIME;
/*
static double sys_offset; /* current local clock offset */
l_fp sys_reftime; /* time we were last updated */
struct peer *sys_peer; /* our current peer */
+struct peer *sys_prefer; /* our cherished peer */
#ifdef AUTOKEY
u_long sys_automax; /* maximum session key lifetime */
#endif /* AUTOKEY */
L_SUB(&ci, &p_reftime);
LFPTOD(&ci, dtemp);
if (PKT_LEAP(pkt->li_vn_mode) == LEAP_NOTINSYNC || /* 6 */
- PKT_TO_STRATUM(pkt->stratum) >= NTP_MAXSTRATUM ||
- dtemp < 0)
+ PKT_TO_STRATUM(pkt->stratum) >= STRATUM_UNSPEC || dtemp < 0)
peer->flash |= TEST6; /* bad synch */
if (!(peer->flags & FLAG_CONFIG) && sys_peer != NULL) { /* 7 */
if (PKT_TO_STRATUM(pkt->stratum) > sys_stratum) {
clock_select(void)
{
register struct peer *peer;
- int i;
+ int i, j, k, n;
int nreach, nlist, nl3;
double d, e, f;
- int j;
- int n;
- int allow, found, k;
+ int allow, found, sw;
double high, low;
double synch[NTP_MAXCLOCK], error[NTP_MAXCLOCK];
struct peer *osys_peer;
struct peer *typeacts = 0;
struct peer *typelocal = 0;
struct peer *typepps = 0;
- struct peer *typeprefer = 0;
struct peer *typesystem = 0;
static int list_alloc = 0;
/*
* Initialize. If a prefer peer does not survive this thing,
- * the pps_update switch will remain zero.
+ * the pps stratum will remain unspec.
*/
- pps_update = 0;
- nreach = nlist = 0;
sys_survivors = 0;
+ sys_prefer = 0;
+ nreach = nlist = 0;
low = 1e9;
high = -1e9;
for (n = 0; n < HASH_SIZE; n++)
if (peer->reach == 0 || (peer->stratum > 1 &&
peer->refid ==
peer->dstadr->sin.sin_addr.s_addr) ||
+ peer->stratum >= STRATUM_UNSPEC ||
(root_distance(peer) >= MAXDISTANCE + 2 *
CLOCK_PHI * ULOGTOD(sys_poll)))
continue;
poll_update(peer_list[i], peer_list[i]->hpoll);
if (peer_list[i]->stratum == peer_list[0]->stratum) {
leap_consensus |= peer_list[i]->leap;
- if (peer_list[i]->refclktype == REFCLK_ATOM_PPS)
+ if (peer_list[i]->refclktype ==
+ REFCLK_ATOM_PPS && peer_list[i]->stratum <
+ STRATUM_UNSPEC)
typepps = peer_list[i];
if (peer_list[i] == sys_peer)
typesystem = peer_list[i];
if (peer_list[i]->flags & FLAG_PREFER) {
- typeprefer = peer_list[i];
- if (fabs(typeprefer->offset) <
- clock_max)
- pps_update = 1;
+ sys_prefer = peer_list[i];
}
} else {
if (peer_list[i] == sys_peer)
* i.e., the stratum of the head of the survivor list.
*/
osys_peer = sys_peer;
- if (typeprefer && (typeprefer->refclktype == REFCLK_LOCALCLOCK
- || typeprefer->sstclktype == CTL_SST_TS_TELEPHONE ||
- !typepps)) {
- sys_peer = typeprefer;
+ if (sys_prefer)
+ sw = sys_prefer->refclktype == REFCLK_LOCALCLOCK ||
+ sys_prefer->sstclktype == CTL_SST_TS_TELEPHONE ||
+ !typepps;
+ else
+ sw = 0;
+ if (sw) {
+ sys_peer = sys_prefer;
sys_peer->status = CTL_PST_SEL_SYSPEER;
sys_offset = sys_peer->offset;
sys_epsil = sys_peer->jitter;
printf("select: prefer offset %.6f\n",
sys_offset);
#endif
- } else if (typepps && pps_update) {
+ } else if (typepps) {
sys_peer = typepps;
sys_peer->status = CTL_PST_SEL_PPS;
sys_offset = sys_peer->offset;
sys_epsil = sys_peer->jitter;
if (!pps_control)
- NLOG(NLOG_SYSEVENT) /* conditional syslog */
- msyslog(LOG_INFO, "pps sync enabled");
+ NLOG(NLOG_SYSEVENT)
+ msyslog(LOG_INFO,
+ "pps sync enabled");
pps_control = current_time;
#ifdef DEBUG
if (debug > 2)
- printf("select: pps offset %.6f\n", sys_offset);
+ printf("select: pps offset %.6f\n",
+ sys_offset);
#endif
} else {
if (!typesystem)
pps_peer = peer;
pp = peer->procptr;
peer->precision = PRECISION;
+ peer->stratum = STRATUM_UNSPEC;
pp->clockdesc = DESCRIPTION;
memcpy((char *)&pp->refid, REFID, 4);
#ifdef HAVE_PPSAPI
if (debug)
printf(
"refclock_atom: %s handle %d ppsapi vers %d mode 0x%x cap 0x%x\n",
- pps_device, up->handle, up->pps_params.api_version,
+ pps_device, (int)up->handle, up->pps_params.api_version,
up->pps_params.mode, mode);
#endif
#endif /* HAVE_PPSAPI */
struct refclockproc *pp;
struct timespec timeout, ts;
double doffset;
- int i, rval;
+ int i;
/*
* Convert the timeval to l_fp and save for billboards. Sign-
timeout.tv_sec = 0;
timeout.tv_nsec = 0;
i = up->pps_info.assert_sequence;
- rval = time_pps_fetch(up->handle, PPS_TSFMT_TSPEC,
- &up->pps_info, &timeout);
- if (rval < 0 || i == up->pps_info.assert_sequence)
+ if (time_pps_fetch(up->handle, PPS_TSFMT_TSPEC,
+ &up->pps_info, &timeout) < 0)
+ return (-1);
+ if (i == up->pps_info.assert_sequence)
return (1);
if (up->pps_info.current_mode & PPS_CAPTUREASSERT)
ts = up->pps_info.assert_timestamp;
else if (up->pps_info.current_mode & PPS_CAPTURECLEAR)
ts = up->pps_info.clear_timestamp;
else
- return (1);
+ return (-1);
if (ts.tv_sec == up->ts.tv_sec && ts.tv_nsec < up->ts.tv_nsec +
RANGEGATE)
return (1);
#endif /* HAVE_PPSAPI */
/*
- * Accumulate samples in the median filter. At the end of each
- * poll interval, do a little bookeeping and process the
- * samples.
+ * Accumulate samples in the median filter. If a noise sample,
+ * return with no prejudice; if a protocol error, get mean;
+ * otherwise, cool. At the end of each poll interval, do a
+ * little bookeeping and process the surviving samples.
*/
pp = peer->procptr;
#ifdef HAVE_PPSAPI
err = atom_pps(peer);
- if (err != 0) {
+ if (err > 0) {
+ return;
+ } else if (err < 0) {
refclock_report(peer, CEVNT_FAULT);
return;
}
#endif /* HAVE_PPSAPI */
+ /*
+ * Valid time is returned only if the prefer peer has survived
+ * the intersection algorithm and within clock_max of local time
+ * and not too long ago. This ensures the PPS time is within
+ * +-0.5 s of the local time and the seconds numbering is
+ * unambiguous. Note that the leap bits are set no-warning on
+ * the first valid update and the stratum is set at the prefer
+ * peer.
+ */
+ peer->stratum = STRATUM_UNSPEC;
+ if (!sys_prefer)
+ return;
+ if (fabs(sys_prefer->offset) > clock_max)
+ return;
+ peer->stratum = sys_prefer->stratum;
+ if (peer->stratum <= 1)
+ peer->refid = pp->refid;
+ else
+ peer->refid = peer->srcadr.sin_addr.s_addr;
+ pp->leap = LEAP_NOWARNING;
pp->polls++;
if (peer->burst > 0)
return;
refclock_report(peer, CEVNT_TIMEOUT);
return;
}
-
- /*
- * Valid time (leap bits zero) is returned only if the prefer
- * peer has survived the intersection algorithm and within
- * clock_max of local time and not too long ago. This ensures
- * the PPS time is within +-0.5 s of the local time and the
- * seconds numbering is unambiguous.
- */
- if (pps_update) {
- pp->leap = LEAP_NOWARNING;
- } else {
- pp->leap = LEAP_NOTINSYNC;
- return;
- }
refclock_receive(peer);
peer->burst = MAXSTAGE;
}
if ((PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER
&& PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE)
- || rpkt->stratum > NTP_MAXSTRATUM) {
+ || rpkt->stratum >= STRATUM_UNSPEC) {
if (debug)
printf("receive: mode %d stratum %d\n",
PKT_MODE(rpkt->li_vn_mode), rpkt->stratum);
if ((PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER
&& PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE)
- || rpkt->stratum > NTP_MAXSTRATUM) {
+ || rpkt->stratum >=STRATUM_UNSPEC) {
if (debug > 1)
printf("receive: mode %d stratum %d\n",
PKT_MODE(rpkt->li_vn_mode), rpkt->stratum);
int sys_timeout = 2; /* timeout time, in seconds */
struct server **sys_servers; /* the server list */
int sys_numservers = 0; /* number of servers to poll */
-int sys_maxservers = NTP_MAXSTRATUM+1; /* max number of servers to deal with */
+int sys_maxservers = STRATUM_UNSPEC; /* max number of servers to deal with */
int sys_version = NTP_OLDVERSION; /* version to poll with */
if ((PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER
&& PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE)
- || rpkt->stratum > NTP_MAXSTRATUM) {
+ || rpkt->stratum >= STRATUM_UNSPEC) {
if (debug)
printf("receive: mode %d stratum %d\n",
PKT_MODE(rpkt->li_vn_mode), rpkt->stratum);