⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 173

📁 Unix/Linux 网络时间协议版本3 Network Time Protocol Version 3 (NTP) distribution for Unix systems
💻
📖 第 1 页 / 共 5 页
字号:
X	 * and so the code must be prepared to handle changing flags.X	 */X	up->sloppyclockflag = pp->sloppyclockflag;X	if (pp->sloppyclockflag & CLK_FLAG2) {X		up->moving = 1;		/* Receiver on mobile platform */X		msyslog(LOG_DEBUG, "jupiter_config: mobile platform");X	} else {X		up->moving = 0;		/* Static Installation */X	}XX	/* XXX fludge flags don't make the trip from the config to here... */X#ifdef notdefX	/* Configure for trailing edge triggers */X#ifdef CIOSETTETX	i = ((pp->sloppyclockflag & CLK_FLAG3) != 0);X	jupiter_debug(peer, "jupiter_configure: (sloppyclockflag 0x%lx)\n",X	    pp->sloppyclockflag);X	if (ioctl(pp->io.fd, CIOSETTET, (char *)&i) < 0)X		msyslog(LOG_DEBUG, "jupiter_configure: CIOSETTET %d: %m", i);X#elseX	if (pp->sloppyclockflag & CLK_FLAG3)X		msyslog(LOG_DEBUG, "jupiter_configure: \XNo kernel support for trailing edge trigger");X#endifX#endifXX	up->pollcnt     = 2;X	up->polled      = 0;X	up->known       = 0;X	up->gweek = 0;X	up->lastsweek = 2 * WEEKSECS;X	up->timecode = 0;X	up->stime = 0;X	up->ssize = 0;X	up->coderecv    = 0;X	up->nkeep       = NKEEP;X	if (up->nkeep > NSAMPLES)X		up->nkeep = NSAMPLES;X	if (up->nkeep >= 1)X		up->rshift = 0;X	if (up->nkeep >= 2)X		up->rshift = 1;X	if (up->nkeep >= 4)X		up->rshift = 2;X	if (up->nkeep >= 8)X		up->rshift = 3;X	if (up->nkeep >= 16)X		up->rshift = 4;X	if (up->nkeep >= 32)X		up->rshift = 5;X	if (up->nkeep >= 64)X		up->rshift = 6;X	up->nkeep = 1;X	i = up->rshift;X	while (i > 0) {X		up->nkeep *= 2;X		i--;X	}XX	/* Stop outputting all messages */X	jupiter_canmsg(peer, JUPITER_ALL);XX	/* Request the receiver id so we can syslog the firmware version */X	jupiter_reqonemsg(peer, JUPITER_O_ID);XX	/* Flag that this the id was requested (so we don't get called again) */X	up->wantid = 1;XX	/* Request perodic time mark pulse messages */X	jupiter_reqmsg(peer, JUPITER_O_PULSE, 1);XX	/* Set application platform type */X	if (up->moving)X		jupiter_platform(peer, JUPITER_I_PLAT_MED);X	elseX		jupiter_platform(peer, JUPITER_I_PLAT_LOW);X}XX/*X * jupiter_poll - jupiter watchdog routineX */Xstatic voidXjupiter_poll(register int unit, register struct peer *peer)X{X	register struct jupiterunit *up;X	register struct refclockproc *pp;XX	pp = peer->procptr;X	up = (struct jupiterunit *)pp->unitptr;XX	/*X	 * You don't need to poll this clock.  It puts out timecodesX	 * once per second.  If asked for a timestamp, take note.X	 * The next time a timecode comes in, it will be fed back.X	 */XX	/*X	 * If we haven't had a response in a while, reset the receiver.X	 */X	if (up->pollcnt > 0) {X		up->pollcnt--;X	} else {X		refclock_report(peer, CEVNT_TIMEOUT);XX		/* Request the receiver id to trigger a reconfig */X		jupiter_reqonemsg(peer, JUPITER_O_ID);X		up->wantid = 0;X	}XX	/*X	 * polled every 64 seconds. Ask jupiter_receive to hand inX	 * a timestamp.X	 */X	up->polled = 1;X	pp->polls++;X}XX/*X * jupiter_receive - receive gps dataX * Gag me!X */Xstatic voidXjupiter_receive(register struct recvbuf *rbufp)X{X	register int bpcnt, cc, size, ppsret;X	register u_int32 last_timecode, laststime;X	register char *cp;X	register u_char *bp;X	register u_short *sp;X	register u_long sloppyclockflag;X	register struct jupiterunit *up;X	register struct jid *ip;X	register struct jheader *hp;X	register struct refclockproc *pp;X	register struct peer *peer;XX	/* Initialize pointers and read the timecode and timestamp */X	peer = (struct peer *)rbufp->recv_srcclock;X	pp = peer->procptr;X	up = (struct jupiterunit *)pp->unitptr;XX	/*X	 * If operating mode has been changed, then reinitialize the receiverX	 * before doing anything else.X	 */X/* XXX Sloppy clock flags are broken!! */X	sloppyclockflag = up->sloppyclockflag;X	up->sloppyclockflag = pp->sloppyclockflag;X	if ((pp->sloppyclockflag & CLK_FLAG2) !=X	    (sloppyclockflag & CLK_FLAG2)) {X		jupiter_debug(peer,X		    "jupiter_receive: mode switch: reset receiver\n");X		jupiter_config(peer);X		return;X	}XX	up->pollcnt = 2;XX	bp = (u_char *)rbufp->recv_buffer;X	bpcnt = rbufp->recv_length;XX	/* This shouldn't happen */X	if (bpcnt > sizeof(up->sbuf) - up->ssize)X		bpcnt = sizeof(up->sbuf) - up->ssize;XX	/* Append to input buffer */X	memcpy((u_char *)up->sbuf + up->ssize, bp, bpcnt);X	up->ssize += bpcnt;XX	/* While there's at least a header and we parse a intact message */X	while (up->ssize > sizeof(*hp) && (cc = jupiter_recv(peer)) > 0) {X		hp = (struct jheader *)up->sbuf;X		sp = (u_short *)(hp + 1);X		size = cc - sizeof(*hp);X		switch (getshort(hp->id)) {XX		case JUPITER_O_PULSE:X			if (size != sizeof(struct jpulse)) {X				jupiter_debug(peer,X				    "jupiter_receive: pulse: len %d != %u\n",X				    size, (int)sizeof(struct jpulse));X				refclock_report(peer, CEVNT_BADREPLY);X				break;X			}XX			/*X			 * There appears to be a firmware bug relatedX			 * to the pulse message; in addition to the oneX			 * per second messages, we get an extra pulseX			 * message once an hour (on the anniversary ofX			 * the cold start). It seems to come 200 msX			 * after the one requested. So if we've seen aX			 * pulse message in the last 210 ms, we skipX			 * this one.X			 */X			laststime = up->stime;X			up->stime = DS2UI(((struct jpulse *)sp)->stime);X			if (laststime != 0 && up->stime - laststime <= 21) {X				jupiter_debug(peer, "jupiter_receive: \Xavoided firmware bug (stime %.2f, laststime %.2f)\n",X    (double)up->stime * 0.01, (double)laststime * 0.01);X				break;X			}XX			/* Retrieve pps timestamp */X			ppsret = jupiter_pps(peer);XX			/* Parse timecode (even when there's no pps) */X			last_timecode = up->timecode;X			if ((cp = jupiter_parse_t(peer, sp)) != NULL) {X				jupiter_debug(peer,X				    "jupiter_receive: pulse: %s\n", cp);X				break;X			}XX			/* Bail if we didn't get a pps timestamp */X			if (ppsret)X				break;XX			/* Bail if we don't have the last timecode yet */X			if (last_timecode == 0)X				break;XX			/* Add the new sample to a median filter */X			if ((cp = jupiter_offset(peer)) != NULL) {X				jupiter_debug(peer,X				    "jupiter_receive: offset: %s\n", cp);X				refclock_report(peer, CEVNT_BADTIME);X				break;X			}XX			/*X			 * The clock will blurt a timecode every secondX			 * but we only want one when polled.  If weX			 * havn't been polled, bail out.X			 */X			if (!up->polled)X				break;XX			/*X			 * It's a live one!  Remember this time.X			 */X			pp->lasttime = current_time;XX			/*X			 * Determine the reference clock offset andX			 * dispersion. NKEEP of NSAMPLE offsets areX			 * passed through a median filter.X			 * Save the (filtered) offset and dispersion inX			 * pp->offset and pp->dispersion.X			 */X			if ((cp = jupiter_process(peer)) != NULL) {X				jupiter_debug(peer,X				    "jupiter_receive: process: %s\n", cp);X				refclock_report(peer, CEVNT_BADTIME);X				break;X			}X			/*X			 * Return offset and dispersion to controlX			 * module. We use lastrec as both the referenceX			 * time and receive time in order to avoidX			 * being cute, like setting the reference timeX			 * later than the receive time, which may causeX			 * a paranoid protocol module to chuck out theX			 * data.X			 */X			jupiter_debug(peer,X			    "jupiter_receive: process time: \X%4d-%03d %02d:%02d:%02d at %s, %s\n",X			    pp->year, pp->day,X			    pp->hour, pp->minute, pp->second,X			    prettydate(&pp->lastrec), lfptoa(&pp->offset, 6));XX			refclock_receive(peer, &pp->offset, 0, pp->dispersion,X				&pp->lastrec, &pp->lastrec, pp->leap);XX			/*X			 * We have succeeded in answering the poll.X			 * Turn off the flag and returnX			 */X			up->polled = 0;X			break;XX		case JUPITER_O_ID:X			if (size != sizeof(struct jid)) {X				jupiter_debug(peer,X				    "jupiter_receive: id: len %d != %u\n",X				    size, (int)sizeof(struct jid));X				refclock_report(peer, CEVNT_BADREPLY);X				break;X			}X			/*X			 * If we got this message because the JupiterX			 * just powered up, it needs to be reconfigured.X			 */X			ip = (struct jid *)sp;X			jupiter_debug(peer,X			    "jupiter_receive: >> %s chan ver %s, %s (%s)\n",X			    ip->chans, ip->vers, ip->date, ip->opts);X			msyslog(LOG_DEBUG,X			    "jupiter_receive: %s chan ver %s, %s (%s)\n",X			    ip->chans, ip->vers, ip->date, ip->opts);X			if (up->wantid)X				up->wantid = 0;X			else {X				jupiter_debug(peer,X				    "jupiter_receive: reset receiver\n");X				jupiter_config(peer);X				/* Rese since jupiter_config() just zeroed it */X				up->ssize = cc;X			}X			break;XX		default:X			jupiter_debug(peer,X			    "jupiter_receive: >> unknown message id %d\n",X			    getshort(hp->id));X			break;X		}X		up->ssize -= cc;X		if (up->ssize < 0) {X			fprintf(stderr, "jupiter_recv: negative ssize!\n");X			abort();X		} else if (up->ssize > 0)X			memcpy(up->sbuf, (u_char *)up->sbuf + cc, up->ssize);X	}X	record_clock_stats(&peer->srcadr, "<timecode is binary>");X}XX/*X * jupiter_offset - Calculate the offset, and add to the rolling filter.X */Xstatic char *Xjupiter_offset(register struct peer *peer)X{X	register struct jupiterunit *up;X	register struct refclockproc *pp;X	register int i;X	l_fp offset;XX	pp = peer->procptr;X	up = (struct jupiterunit *)pp->unitptr;XX	/*X	 * Calculate the offsetX	 */X	if (!clocktime(pp->day, pp->hour, pp->minute, pp->second, GMT,X		pp->lastrec.l_ui, &pp->yearstart, &offset.l_ui)) {X		return ("jupiter_process: clocktime failed");X	}X	if (pp->usec) {X		TVUTOTSF(pp->usec, offset.l_uf);X	} else {X		MSUTOTSF(pp->msec, offset.l_uf);X	}X	L_ADD(&offset, &pp->fudgetime1);X	up->lastref = offset;   /* save last reference time */X	L_SUB(&offset, &pp->lastrec); /* form true offset */XX	/*X	 * A rolling filter.  Initialize first time around.X	 */X	i = ((up->coderecv)) % NSAMPLES;XX	up->filter[i] = offset;X	if (up->coderecv == 0)X		for (i = 1; (u_int) i < NSAMPLES; i++)X			up->filter[i] = up->filter[0];X	up->coderecv++;XX	return (NULL);X}XX/*X * jupiter_process - process the sample from the clock,X * passing it through a median filter and optionally averagingX * the samples.  Returns offset and dispersion in "up" structure.X */Xstatic char *Xjupiter_process(register struct peer *peer)X{X	register struct jupiterunit *up;X	register struct refclockproc *pp;X	register int i, n;X	register int j, k;X	l_fp offset, median, lftmp;X	u_fp disp;X	l_fp off[NSAMPLES];XX	pp = peer->procptr;X	up = (struct jupiterunit *)pp->unitptr;XX	/*X	 * Copy the raw offsets and sort into ascending orderX	 */X	for (i = 0; i < NSAMPLES; i++)X		off[i] = up->filter[i];X	qsort((char *)off, NSAMPLES, sizeof(l_fp), jupiter_cmpl_fp);XX	/*X	 * Reject the furthest from the median of NSAMPLES samples untilX	 * NKEEP samples remain.X	 */X	i = 0;X	n = NSAMPLES;X	while ((n - i) > up->nkeep) {X		lftmp = off[n - 1];X		median = off[(n + i) / 2];X		L_SUB(&lftmp, &median);X		L_SUB(&median, &off[i]);X		if (L_ISHIS(&median, &lftmp)) {X			/* reject low end */X			i++;X		} else {X			/* reject high end */X			n--;X		}X	}XX	/*X	 * Copy key values to the billboard to measure performance.X	 */X	pp->lastref = up->lastref;X	pp->coderecv = up->coderecv;X	pp->nstages = up->nkeep + 2;X	pp->filter[0] = off[0];			/* smallest offset */X	pp->filter[1] = off[NSAMPLES-1];	/* largest offset */X	for (j = 2, k = i; k < n; j++, k++)X		pp->filter[j] = off[k];		/* offsets actually examined */XX	/*X	 * Compute the dispersion based on the difference between theX	 * extremes of the remaining offsets. Add to this the time sinceX	 * the last clock update, which represents the dispersionX	 * increase with time. We know that NTP_MAXSKEW is 16. If theX	 * sum is greater than the allowed sample dispersion, bail out.X	 * If the loop is unlocked, return the most recent offset;X	 * otherwise, return the median offset.X	 */X	lftmp = off[n - 1];X	L_SUB(&lftmp, &off[i]);X	disp = LFPTOFP(&lftmp);X	if (disp > REFCLOCKMAXDISPERSE)X		return ("Maximum dispersion exceeded");XX	/*X	 * Now compute the offset estimate.  If fudge flag 1X	 * is set, average the remainder, otherwise pick theX	 * median.X	 */X	if (pp->sloppyclockflag & CLK_FLAG1) {X		L_CLR(&lftmp);X		while (i < n) {X			L_ADD(&lftmp, &off[i]);X			i++;X		}X		i = up->rshift;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -