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

📄 173

📁 Unix/Linux 网络时间协议版本3 Network Time Protocol Version 3 (NTP) distribution for Unix systems
💻
📖 第 1 页 / 共 5 页
字号:
X		while (i > 0) {X			L_RSHIFT(&lftmp);X			i--;X		}X		offset = lftmp;X	} else {X		i = (n + i) / 2;X		offset = off[i];X	}XX	/*X	 * The payload: filtered offset and dispersion.X	 */XX	pp->offset = offset;X	pp->dispersion = disp;XX	return (NULL);XX}XX/* Compare two l_fp's, used with qsort() */XintX#ifdef QSORT_USES_VOID_PXjupiter_cmpl_fp(register const void *p1, register const void *p2)X#elseXjupiter_cmpl_fp(register const l_fp *fp1, register const l_fp *fp2)X#endifX{X#ifdef QSORT_USES_VOID_PX	register const l_fp *fp1 = (const l_fp *)p1;X	register const l_fp *fp2 = (const l_fp *)p2;X#endifXX	if (!L_ISGEQ(fp1, fp2))X		return (-1);X	if (L_ISEQU(fp1, fp2))X		return (0);X	return (1);X}XXstatic char *Xjupiter_parse_t(register struct peer *peer, register u_short *sp)X{X	register struct refclockproc *pp;X	register struct jupiterunit *up;X	register struct tm *tm;X	register char *cp;X	register struct jpulse *jp;X	register struct calendar *jt;X	register u_int32 sweek;X	register u_int32 last_timecode;X	register u_short flags;X	time_t t;X	struct calendar cal;XX	pp = peer->procptr;X	up = (struct jupiterunit *)pp->unitptr;X	jp = (struct jpulse *)sp;XX	/* The timecode is presented as seconds into the current GPS week */X	sweek = DS2UI(jp->sweek);XX	/*X	 * If we don't know the current GPS week, calculate it from theX	 * current time. (It's too bad they didn't include thisX	 * important value in the pulse message). We'd like to pick itX	 * up from one of the other messages like gpos or chan but theyX	 * don't appear to be synchronous with time keeping and changesX	 * too soon (something like 10 seconds before the new GPSX	 * week).X	 *X	 * If we already know the current GPS week, increment it whenX	 * we wrap into a new week.X	 */X	if (up->gweek == 0)X		up->gweek = (time(NULL) - GPS_EPOCH) / WEEKSECS;X	else if (sweek == 0 && up->lastsweek == WEEKSECS - 1) {X		++up->gweek;X		jupiter_debug(peer,X		    "jupiter_parse_t: NEW gps week %u\n", up->gweek);X	}XX	/*X	 * See if the sweek stayed the same (this happens when there isX	 * no pps pulse).X	 *X	 * Otherwise, look for time warps:X	 *X	 *   - we have stored at least one lastsweek andX	 *   - the sweek didn't increase by one andX	 *   - we didn't wrap to a new GPS weekX	 *X	 * Then we warped.X	 */X	if (up->lastsweek == sweek)X		jupiter_debug(peer,X		    "jupiter_parse_t: gps sweek not incrementing (%d)\n",X		    sweek);X	else if (up->lastsweek != 2 * WEEKSECS &&X	    up->lastsweek + 1 != sweek &&X	    !(sweek == 0 && up->lastsweek == WEEKSECS - 1))X		jupiter_debug(peer,X		    "jupiter_parse_t: gps sweek jumped (was %d, now %d)\n",X		    up->lastsweek, sweek);X	up->lastsweek = sweek;XX	/* This timecode describes next pulse */X	last_timecode = up->timecode;X	up->timecode = (u_int32)JAN_1970 +X	    GPS_EPOCH + (up->gweek * WEEKSECS) + sweek;XX	if (last_timecode == 0)X		/* XXX debugging */X		jupiter_debug(peer,X		    "jupiter_parse_t: UTC <none> (gweek/sweek %u/%u)\n",X		    up->gweek, sweek);X	else {X		/* XXX debugging */X		t = last_timecode - (u_int32)JAN_1970;X		tm = gmtime(&t);X		cp = asctime(tm);XX		jupiter_debug(peer,X		    "jupiter_parse_t: UTC %.24s (gweek/sweek %u/%u)\n",X		    cp, up->gweek, sweek);XX		/* Billboard last_timecode (which is now the current time) */X		jt = &cal;X		caljulian(last_timecode, jt);X		pp = peer->procptr;X		pp->year = jt->year;X		pp->day = jt->yearday;X		pp->hour = jt->hour;X		pp->minute = jt->minute;X		pp->second = jt->second;X		pp->msec = 0;X		pp->usec = 0;X	}XX	/* XXX debugging */X	tm = gmtime(&up->ppsev.tv.tv_sec);X	cp = asctime(tm);X	flags = getshort(jp->flags);X	jupiter_debug(peer,X	    "jupiter_parse_t: PPS %.19s.%06lu %.4s (serial %u)%s\n",X	    cp, up->ppsev.tv.tv_usec, cp + 20, up->ppsev.serial,X	    (flags & JUPITER_O_PULSE_VALID) == 0 ?X	    " NOT VALID" : "");XX	/* Toss if not designated "valid" by the gps */X	if ((flags & JUPITER_O_PULSE_VALID) == 0) {X		refclock_report(peer, CEVNT_BADTIME);X		return ("time mark not valid");X	}XX	/* We better be sync'ed to UTC... */X	if ((flags & JUPITER_O_PULSE_UTC) == 0) {X		refclock_report(peer, CEVNT_BADTIME);X		return ("time mark not sync'ed to UTC");X	}XX	return (NULL);X}XX/*X * Process a PPS signal, returning a timestamp.X */Xstatic intXjupiter_pps(register struct peer *peer)X{X	register struct refclockproc *pp;X	register struct jupiterunit *up;X	register int firsttime;X	struct timeval ntp_tv;XX	pp = peer->procptr;X	up = (struct jupiterunit *)pp->unitptr;XX	/*X	 * Grab the timestamp of the PPS signal.X	 */X	firsttime = (up->ppsev.tv.tv_sec == 0);X	if (ioctl(pp->io.fd, CIOGETEV, (caddr_t)&up->ppsev) < 0) {X		/* XXX Actually, if this fails, we're pretty much screwed */X		jupiter_debug(peer, "jupiter_pps: CIOGETEV: %s\n",X		    strerror(errno));X		refclock_report(peer, CEVNT_FAULT);X		return (1);X	}XX	/*X	 * Check pps serial number against last oneX	 */X	if (!firsttime && up->lastserial + 1 != up->ppsev.serial) {X		if (up->ppsev.serial == up->lastserial)X			jupiter_debug(peer, "jupiter_pps: no new pps event\n");X		elseX			jupiter_debug(peer,X			    "jupiter_pps: missed %d pps events\n",X				up->ppsev.serial - up->lastserial - 1);X		up->lastserial = up->ppsev.serial;X		refclock_report(peer, CEVNT_FAULT);X		return (1);X	}X	up->lastserial = up->ppsev.serial;XX	/*X	 * Return the timestamp in pp->lastrecX	 */X	ntp_tv = up->ppsev.tv;X	ntp_tv.tv_sec += (u_int32)JAN_1970;X	TVTOTS(&ntp_tv, &pp->lastrec);XX	return (0);X}XX/*X * jupiter_debug - print debug messagesX */X#if __STDC__Xstatic voidXjupiter_debug(struct peer *peer, char *fmt, ...)X#elseXstatic voidXjupiter_debug(peer, fmt, va_alist)X	struct peer *peer;X	char *fmt;X#endifX{X	va_list ap;XX	if (debug) {XX#if __STDC__X		va_start(ap, fmt);X#elseX		va_start(ap);X#endifX		/*X		 * Print debug message to stdoutX		 * In the future, we may want to get get more creative...X		 */X		vfprintf(stderr, fmt, ap);XX		va_end(ap);X	}X}XX/* Checksum and transmit a message to the Jupiter */Xstatic char *Xjupiter_send(register struct peer *peer, register struct jheader *hp)X{X	register u_int len, size;X	register int cc;X	register u_short *sp;X	static char errstr[132];XX	size = sizeof(*hp);X	hp->hsum = putshort(jupiter_cksum((u_short *)hp,X	    (size / sizeof(u_short)) - 1));X	len = getshort(hp->len);X	if (len > 0) {X		sp = (u_short *)(hp + 1);X		sp[len] = putshort(jupiter_cksum(sp, len));X		size += (len + 1) * sizeof(u_short);X	}XX	if ((cc = write(peer->procptr->io.fd, (char *)hp, size)) < 0) {X		(void)sprintf(errstr, "write: %s", strerror(errno));X		return (errstr);X	} else if (cc != size) {X		(void)sprintf(errstr, "short write (%d != %d)", cc, size);X		return (errstr);X	}X	return (NULL);X}XX/* Request periodic message output */Xstatic struct {X	struct jheader jheader;X	struct jrequest jrequest;X} reqmsg = {X	{ putshort(JUPITER_SYNC), 0,X	    putshort((sizeof(struct jrequest) / sizeof(u_short)) - 1),X	    0, putshort(JUPITER_FLAG_REQUEST | JUPITER_FLAG_NAK |X	    JUPITER_FLAG_CONN | JUPITER_FLAG_LOG), 0 },X	{ 0, 0, 0, 0 }X};XX/* An interval of zero means to output on trigger */Xstatic voidXjupiter_reqmsg(register struct peer *peer, register u_int id,X    register u_int interval)X{X	register struct jheader *hp;X	register struct jrequest *rp;X	register char *cp;XX	hp = &reqmsg.jheader;X	hp->id = putshort(id);X	rp = &reqmsg.jrequest;X	rp->trigger = putshort(interval == 0);X	rp->interval = putshort(interval);X	if ((cp = jupiter_send(peer, hp)) != NULL)X		jupiter_debug(peer, "jupiter_reqmsg: %u: %s\n", id, cp);X}XX/* Cancel periodic message output */Xstatic struct jheader canmsg = {X	putshort(JUPITER_SYNC), 0, 0, 0,X	putshort(JUPITER_FLAG_REQUEST | JUPITER_FLAG_NAK | JUPITER_FLAG_DISC),X	0X};XXstatic voidXjupiter_canmsg(register struct peer *peer, register u_int id)X{X	register struct jheader *hp;X	register char *cp;XX	hp = &canmsg;X	hp->id = putshort(id);X	if ((cp = jupiter_send(peer, hp)) != NULL)X		jupiter_debug(peer, "jupiter_canmsg: %u: %s\n", id, cp);X}XX/* Request a single message output */Xstatic struct jheader reqonemsg = {X	putshort(JUPITER_SYNC), 0, 0, 0,X	putshort(JUPITER_FLAG_REQUEST | JUPITER_FLAG_NAK | JUPITER_FLAG_QUERY),X	0X};XXstatic voidXjupiter_reqonemsg(register struct peer *peer, register u_int id)X{X	register struct jheader *hp;X	register char *cp;XX	hp = &reqonemsg;X	hp->id = putshort(id);X	if ((cp = jupiter_send(peer, hp)) != NULL)X		jupiter_debug(peer, "jupiter_reqonemsg: %u: %s\n", id, cp);X}XX/* Set the platform dynamics */Xstatic struct {X	struct jheader jheader;X	struct jplat jplat;X} platmsg = {X	{ putshort(JUPITER_SYNC), putshort(JUPITER_I_PLAT),X	    putshort((sizeof(struct jplat) / sizeof(u_short)) - 1), 0,X	    putshort(JUPITER_FLAG_REQUEST | JUPITER_FLAG_NAK), 0 },X	{ 0, 0, 0 }X};XXstatic voidXjupiter_platform(register struct peer *peer, register u_int platform)X{X	register struct jheader *hp;X	register struct jplat *pp;X	register char *cp;XX	hp = &platmsg.jheader;X	pp = &platmsg.jplat;X	pp->platform = putshort(platform);X	if ((cp = jupiter_send(peer, hp)) != NULL)X		jupiter_debug(peer, "jupiter_platform: %u: %s\n", platform, cp);X}XX/* Checksum "len" shorts */Xstatic u_shortXjupiter_cksum(register u_short *sp, register u_int len)X{X	register u_short sum, x;XX	sum = 0;X	while (len-- > 0) {X		x = *sp++;X		sum += getshort(x);X	}X	return (~sum + 1);X}XX/* Return the size of the next message (or zero if we don't have it all yet) */Xstatic intXjupiter_recv(register struct peer *peer)X{X	register int n, len, size, cc;X	register struct refclockproc *pp;X	register struct jupiterunit *up;X	register struct jheader *hp;X	register u_char *bp;X	register u_short *sp;XX	pp = peer->procptr;X	up = (struct jupiterunit *)pp->unitptr;XX	/* Must have at least a header's worth */X	cc = sizeof(*hp);X	size = up->ssize;X	if (size < cc)X		return (0);XX	/* Search for the sync short if missing */X	sp = up->sbuf;X	hp = (struct jheader *)sp;X	if (getshort(hp->sync) != JUPITER_SYNC) {X		/* Wasn't at the front, sync up */X		jupiter_debug(peer, "syncing");X		bp = (u_char *)sp;X		n = size;X		while (n >= 2) {X			if (bp[0] != (JUPITER_SYNC & 0xff)) {X				jupiter_debug(peer, "{0x%x}", bp[0]);X				++bp;X				--n;X				continue;X			}X			if (bp[1] == ((JUPITER_SYNC >> 8) & 0xff))X				break;X			jupiter_debug(peer, "{0x%x 0x%x}", bp[0], bp[1]);X			bp += 2;X			n -= 2;X		}X		jupiter_debug(peer, "\n");X		/* Shuffle data to front of input buffer */X		if (n > 0)X			memcpy(sp, bp, n);X		size = n;X		up->ssize = size;X		if (size < cc || hp->sync != JUPITER_SYNC)X			return (0);X	}XX	if (jupiter_cksum(sp, (cc / sizeof(u_short) - 1)) !=X	    getshort(hp->hsum)) {X	    jupiter_debug(peer, "jupiter_recv: bad header checksum!\n");X		/* This is drastic but checksum errors should be rare */X		up->ssize = 0;X		return (0);X	}XX	/* Check for a payload */X	len = getshort(hp->len);X	if (len > 0) {X		n = (len + 1) * sizeof(u_short);X		/* Not enough data yet */X		if (size < cc + n)X			return (0);XX		/* Check payload checksum */X		sp = (u_short *)(hp + 1);X		if (jupiter_cksum

⌨️ 快捷键说明

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