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

📄 refclock_msfees.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 4 页
字号:
			ees->unit, msec(delta_sfsec), subms(delta_sfsec), ees->second,			old_sincelast, ees->last_step_late, count, sum, ees->last_step_secs);		if (sum) ees->last_step_secs = sum;	}	/* OK, so not a 4ms step at a minute boundry */	else {		if (suspect_4ms_step) msyslog(LOG_ERR,					      "MSF%d: suspect = %x, but delta of %d.%04d [%d.%04d<%d.%04d<%d.%04d: %d %d]",					      ees->unit, suspect_4ms_step, msec(delta_sfsec), subms(delta_sfsec),					      msec(EES_STEP_F - EES_STEP_F_GRACE),					      subms(EES_STEP_F - EES_STEP_F_GRACE),					      (int)msec(delta_f_abs),					      (int)subms(delta_f_abs),					      msec(EES_STEP_F + EES_STEP_F_GRACE),					      subms(EES_STEP_F + EES_STEP_F_GRACE),					      ees->second,					      sincelast);		if ((delta_f_abs > EES_STEP_NOTE) && ees->last_l.l_i) {			static int ees_step_notes = EES_STEP_NOTES;			if (ees_step_notes > 0) {				ees_step_notes--;				printf("MSF%d: D=%3ld.%04ld@%02d :%d%s\n",				       ees->unit, (long)msec(delta_sfsec), (long)subms(delta_sfsec),				       ees->second, sincelast, ees_step_notes ? "" : " -- NO MORE !");				msyslog(LOG_ERR, "MSF%d: D=%3d.%04d@%02d :%d%s",					ees->unit, msec(delta_sfsec), subms(delta_sfsec), ees->second, (ees->last_step) ? sincelast : -1, ees_step_notes ? "" : " -- NO MORE !");			}		}	}	}	ees->last_l = ees->arrvtime;	/* IF we have found that it's ramping	 * && it's within twice the expected ramp period	 * && there is a non zero step size (avoid /0 !)	 * THEN we twiddle things	 */	if (ees->using_ramp &&	    sincelast < (ees->last_step_secs)*2 &&	    ees->last_step_secs)	{	long	sec_of_ramp = sincelast + ees->last_step_late;	long	fsecs;	l_fp	inc;	/* Ramp time may vary, so may ramp for longer than last time */	if (sec_of_ramp > (ees->last_step_secs + 120))	    sec_of_ramp =  ees->last_step_secs;	/* sec_of_ramp * ees->jump_fsecs may overflow 2**32 */	fsecs = sec_of_ramp * (ees->jump_fsecs /  ees->last_step_secs);	if (debug & DB_LOG_DELTAS) msyslog(LOG_ERR,					   "[%x] MSF%d: %3ld/%03d -> d=%11ld (%d|%ld)",					   DB_LOG_DELTAS,					   ees->unit, sec_of_ramp, ees->last_step_secs, fsecs,					   pps_arrvstamp.l_f, pps_arrvstamp.l_f + fsecs);	if (debug & DB_PRINT_DELTAS) printf(		"MSF%d: %3ld/%03d -> d=%11ld (%ld|%ld)\n",		ees->unit, sec_of_ramp, ees->last_step_secs, fsecs,		(long)pps_arrvstamp.l_f, pps_arrvstamp.l_f + fsecs);	/* Must sign extend the result */	inc.l_i = (fsecs < 0) ? -1 : 0;	inc.l_f = fsecs;	if (debug & DB_INC_PPS)	{	L_SUB(&pps_arrvstamp, &inc);	L_SUB(&ees->arrvtime, &inc);	}	else	{	L_ADD(&pps_arrvstamp, &inc);	L_ADD(&ees->arrvtime, &inc);	}	}	else {		if (debug & DB_LOG_DELTAS) msyslog(LOG_ERR,						   "[%x] MSF%d: ees->using_ramp=%d, sincelast=%x / %x, ees->last_step_secs=%x",						   DB_LOG_DELTAS,						   ees->unit, ees->using_ramp,						   sincelast,						   (ees->last_step_secs)*2,						   ees->last_step_secs);		if (debug & DB_PRINT_DELTAS) printf(			"[%x] MSF%d: ees->using_ramp=%d, sincelast=%x / %x, ees->last_step_secs=%x\n",			DB_LOG_DELTAS,			ees->unit, ees->using_ramp,			sincelast,			(ees->last_step_secs)*2,			ees->last_step_secs);	}	L_SUB(&ees->arrvtime, &offset_fudge[ees->unit]);	L_SUB(&pps_arrvstamp, &offset_fudge[ees->unit]);	if (call_pps_sample && !(debug & DB_NO_PPS)) {		/* Sigh -- it expects its args negated */		L_NEG(&pps_arrvstamp);		/*		 * I had to disable this here, since it appears there is no pointer to the		 * peer structure.		 *		 (void) pps_sample(peer, &pps_arrvstamp);		*/	}	/* Subtract off the local clock time stamp */	L_SUB(&ees->codeoffsets[n_sample], &ees->arrvtime);	if (debug & DB_LOG_SAMPLES) msyslog(LOG_ERR,					    "MSF%d: [%x] %d (ees: %d %d) (pps: %d %d)%s",					    ees->unit, DB_LOG_DELTAS, n_sample,					    ees->codeoffsets[n_sample].l_f,					    ees->codeoffsets[n_sample].l_f / 4295,					    pps_arrvstamp.l_f,					    pps_arrvstamp.l_f /4295,					    (debug & DB_NO_PPS) ? " [no PPS]" : "");	if (ees->nsamples++ == NCODES-1) ees_process(ees);	/* Done! */}/* offcompare - auxiliary comparison routine for offset sort */#ifdef QSORT_USES_VOID_Pstatic intoffcompare(	const void *va,	const void *vb	){	const l_fp *a = (const l_fp *)va;	const l_fp *b = (const l_fp *)vb;	return(L_ISGEQ(a, b) ? (L_ISEQU(a, b) ? 0 : 1) : -1);}#elsestatic intoffcompare(	const l_fp *a,	const l_fp *b	){	return(L_ISGEQ(a, b) ? (L_ISEQU(a, b) ? 0 : 1) : -1);}#endif /* QSORT_USES_VOID_P *//* ees_process - process a pile of samples from the clock */static voidees_process(	struct eesunit *ees	){	static int last_samples = -1;	register int i, j;	register int noff;	register l_fp *coffs = ees->codeoffsets;	l_fp offset, tmp;	double dispersion;	/* ++++ */	int lostsync, isinsync;	int samples = ees->nsamples;	int samplelog = 0;	/* keep "gcc -Wall" happy ! */	int samplereduce = (samples + 1) / 2;	double doffset;	/* Reset things to zero so we don't have to worry later */	ees_reset(ees);	if (sloppyclockflag[ees->unit]) {		samplelog = (samples <  2) ? 0 :			(samples <  5) ? 1 :			(samples <  9) ? 2 :			(samples < 17) ? 3 :			(samples < 33) ? 4 : 5;		samplereduce = (1 << samplelog);	}	if (samples != last_samples &&	    ((samples != (last_samples-1)) || samples < 3)) {		msyslog(LOG_ERR, "Samples=%d (%d), samplereduce=%d ....",			samples, last_samples, samplereduce);		last_samples = samples;	}	if (samples < 1) return;	/* If requested, dump the raw data we have in the buffer */	if (ees->dump_vals) dump_buf(coffs, 0, samples, "Raw  data  is:");	/* Sort the offsets, trim off the extremes, then choose one. */	qsort(#ifdef QSORT_USES_VOID_P	    (void *)#else	    (char *)#endif	    coffs, (size_t)samples, sizeof(l_fp), offcompare);	noff = samples;	i = 0;	while ((noff - i) > samplereduce) {		/* Trim off the sample which is further away		 * from the median.  We work this out by doubling		 * the median, subtracting off the end samples, and		 * looking at the sign of the answer, using the		 * identity (c-b)-(b-a) == 2*b-a-c		 */		tmp = coffs[(noff + i)/2];		L_ADD(&tmp, &tmp);		L_SUB(&tmp, &coffs[i]);		L_SUB(&tmp, &coffs[noff-1]);		if (L_ISNEG(&tmp)) noff--; else i++;	}	/* If requested, dump the reduce data we have in the buffer */	if (ees->dump_vals) dump_buf(coffs, i, noff, "Reduced    to:");	/* What we do next depends on the setting of the sloppy clock flag.	 * If it is on, average the remainder to derive our estimate.	 * Otherwise, just pick a representative value from the remaining stuff	 */	if (sloppyclockflag[ees->unit]) {		offset.l_ui = offset.l_uf = 0;		for (j = i; j < noff; j++)		    L_ADD(&offset, &coffs[j]);		for (j = samplelog; j > 0; j--)		    L_RSHIFTU(&offset);	}	else offset = coffs[i+BESTSAMPLE];	/* Compute the dispersion as the difference between the	 * lowest and highest offsets that remain in the	 * consideration list.	 *	 * It looks like MOST clocks have MOD (max error), so halve it !	 */	tmp = coffs[noff-1];	L_SUB(&tmp, &coffs[i]);#define	FRACT_SEC(n) ((1 << 30) / (n/2))	dispersion = LFPTOFP(&tmp) / 2; /* ++++ */	if (debug & (DB_SYSLOG_SMPLI | DB_SYSLOG_SMPLE)) msyslog(		(debug & DB_SYSLOG_SMPLE) ? LOG_ERR : LOG_INFO,		"I: [%x] Offset=%06d (%d), disp=%f%s [%d], %d %d=%d %d:%d %d=%d %d",		debug & (DB_SYSLOG_SMPLI | DB_SYSLOG_SMPLE),		offset.l_f / 4295, offset.l_f,		(dispersion * 1526) / 100,		(sloppyclockflag[ees->unit]) ? " by averaging" : "",		FRACT_SEC(10) / 4295,		(coffs[0].l_f) / 4295,		i,		(coffs[i].l_f) / 4295,		(coffs[samples/2].l_f) / 4295,		(coffs[i+BESTSAMPLE].l_f) / 4295,		noff-1,		(coffs[noff-1].l_f) / 4295,		(coffs[samples-1].l_f) / 4295);	/* Are we playing silly wotsits ?	 * If we are using all data, see if there is a "small" delta,	 * and if so, blurr this with 3/4 of the delta from the last value	 */	if (ees->usealldata && ees->offset.l_uf) {		long diff = (long) (ees->offset.l_uf - offset.l_uf);		/* is the delta small enough ? */		if ((- FRACT_SEC(100)) < diff && diff < FRACT_SEC(100)) {			int samd = (64 * 4) / samples;			long new;			if (samd < 2) samd = 2;			new = offset.l_uf + ((diff * (samd -1)) / samd);			/* Sign change -> need to fix up int part */			if ((new & 0x80000000) !=			    (((long) offset.l_uf) & 0x80000000))			{	NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */					msyslog(LOG_INFO, "I: %lx != %lx (%lx %lx), so add %d",						new & 0x80000000,						((long) offset.l_uf) & 0x80000000,						new, (long) offset.l_uf,						(new < 0) ? -1 : 1);				offset.l_ui += (new < 0) ? -1 : 1;			}			dispersion /= 4;			if (debug & (DB_SYSLOG_SMTHI | DB_SYSLOG_SMTHE)) msyslog(				(debug & DB_SYSLOG_SMTHE) ? LOG_ERR : LOG_INFO,				"I: [%x] Smooth data: %ld -> %ld, dispersion now %f",				debug & (DB_SYSLOG_SMTHI | DB_SYSLOG_SMTHE),				((long) offset.l_uf) / 4295, new / 4295,				(dispersion * 1526) / 100);			offset.l_uf = (unsigned long) new;		}		else if (debug & (DB_SYSLOG_NSMTHI | DB_SYSLOG_NSMTHE)) msyslog(			(debug & DB_SYSLOG_NSMTHE) ? LOG_ERR : LOG_INFO,			"[%x] No smooth as delta not %d < %ld < %d",			debug & (DB_SYSLOG_NSMTHI | DB_SYSLOG_NSMTHE),			- FRACT_SEC(100), diff, FRACT_SEC(100));	}	else if (debug & (DB_SYSLOG_NSMTHI | DB_SYSLOG_NSMTHE)) msyslog(		(debug & DB_SYSLOG_NSMTHE) ? LOG_ERR : LOG_INFO,		"I: [%x] No smooth as flag=%x and old=%x=%d (%d:%d)",		debug & (DB_SYSLOG_NSMTHI | DB_SYSLOG_NSMTHE),		ees->usealldata, ees->offset.l_f, ees->offset.l_uf,		offset.l_f, ees->offset.l_f - offset.l_f);	/* Collect offset info for debugging info */	ees->offset = offset;	ees->lowoffset = coffs[i];	ees->highoffset = coffs[noff-1];	/* Determine synchronization status.  Can be unsync'd either	 * by a report from the clock or by a leap hold.	 *	 * Loss of the radio signal for a short time does not cause	 * us to go unsynchronised, since the receiver keeps quite	 * good time on its own.  The spec says 20ms in 4 hours; the	 * observed drift in our clock (Cambridge) is about a second	 * a day, but even that keeps us within the inherent tolerance	 * of the clock for about 15 minutes. Observation shows that	 * the typical "short" outage is 3 minutes, so to allow us	 * to ride out those, we will give it 5 minutes.	 */	lostsync = current_time - ees->clocklastgood > 300 ? 1 : 0;	isinsync = (lostsync || ees->leaphold > current_time) ? 0 : 1;	/* Done.  Use time of last good, synchronised code as the	 * reference time, and lastsampletime as the receive time.	 */	if (ees->fix_pending) {		msyslog(LOG_ERR, "MSF%d: fix_pending=%d -> jump %x.%08x\n",			ees->fix_pending, ees->unit, offset.l_i, offset.l_f);		ees->fix_pending = 0;	}	LFPTOD(&offset, doffset);	refclock_receive(ees->peer);	ees_event(ees, lostsync ? CEVNT_PROP : CEVNT_NOMINAL);}/* msfees_poll - called by the transmit procedure */static voidmsfees_poll(	int unit,	struct peer *peer	){	if (unit >= MAXUNITS) {		msyslog(LOG_ERR, "ees clock poll: INTERNAL: unit %d invalid",			unit);		return;	}	if (!unitinuse[unit]) {		msyslog(LOG_ERR, "ees clock poll: INTERNAL: unit %d unused",			unit);		return;	}	ees_process(eesunits[unit]);	if ((current_time - eesunits[unit]->lasttime) > 150)	    ees_event(eesunits[unit], CEVNT_FAULT);}#elseint refclock_msfees_bs;#endif /* REFCLOCK */

⌨️ 快捷键说明

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